obj_save

obj_save speichert ein Objekt in einer Datei oder in einer Zeichenkette als XML-Datei oder Binärdatei.

ret = obj_save(obj, ssFilename)
ret = obj_save(obj, ssFilename, ssFormat)
ssXMLString = obj_save(obj, "")

Returnwert

Falls ssFilename ein vollständiger Dateiname ist, ist ret ungleich 0, wenn die Funktion erfolgreich war und 0 wenn die Funktion fehlgeschlagen ist. Falls der Dateiname die Extension .uso (für Uni Script Object) hat, wird die Datei in einem binären Format gespeichert.

Falls ssFilename ein leerer String ("") ist, ist der Returnwert ein String mit dem XML-Code des Objekts obj oder, falls für ssFormat "binary", "b" oder "uncompressed-binary" oder "u" angegeben wurde, das Objekt in einem Binärformat.

Parameter

obj

obj ist ein mit obj_create erzeugtes Objekt.

ssFilename

ssFilename ist der komplette Dateiname oder ein leerer String ("") (siehe ret).

ssFormat

ssFormat ist entweder ein Format-String der angibt, wie Zahlen gespeichert werden sollen (siehe printf) (der Default-Wert ist "%.20g") oder der String "binary" oder "b" bzw. "uncompressed-binary" oder "u" um die Datei in einem binären Dateiformat zu speichern.

Beispiel

obj = obj_create()
obj[1] = 123
obj.a = "Hello"
obj.c = obj_create()
obj.c.d = 456
obj.save("d:\\test.xml")

erzeugt die folgende xml-Datei:

<?xml version='1.0' encoding='utf-8'?>
<obj id='1'>
    <number ikey='1'>123</number>
    <string key='a'>Hello</string>
    <obj id='2' key='c'>
        <number key='d'>456</number>
    </obj>
</obj>

Ein leerer String speichert den XML-Text in einem String:

s = obj.save("")

Die Angabe "binary" erzeugt ein binäres Format:

s = obj.save("", "binary")
mem_dump(s)

Kommentar

Anmerkungen

  • Das Speichern von Objekten als Binärdatei ist wesentlich schneller als das Speichern als XML-Datei, insbesondere wenn die Datei viele große Vektoren oder Matrizen enthält, Faktor 50 oder mehr.
  • Das Speichern in einem String eignet sich nur für Objekte mit einigen, wenigen MB. Größere Objekte mit mehreren Megabytes an Daten sollten in Dateien gespeichert werden.

XML-Schema

Beschreibung des relax-ng Schemas der XML-Dateien (siehe auch http://relaxng.org/compact-tutorial-20030326.html):

obj = element obj { obj_attlist, (obj_inner | simple)* }
obj_attlist = attribute id { xsd:positiveInteger }?

simple =
  number
  | \string
  | complex
  | number-matrix
  | string-matrix
  | complex-matrix
  | variant-matrix

obj_inner = element obj { obj_inner_attlist, simple* }
obj_inner_attlist =
  key_or_ikey,
  attribute id { xsd:positiveInteger }?,
  attribute ref { xsd:positiveInteger }?
#
number = element number { key_or_ikey, xsd:double }
\string = element string { string_attlist, text }
string_attlist =
  key_or_ikey,
  attribute encoding { xsd:string "base64" }?
complex = element complex { key_or_ikey, cpx }
#
mat_number = element number { xsd:double }
mat_string = element string { mat_string_attlist, text }
mat_string_attlist = attribute encoding { xsd:string "base64" }?
mat_complex = element complex { cpx }
#
number-matrix = element number-matrix { matrix_attlist, mat_number+ }
string-matrix = element string-matrix { matrix_attlist, mat_string+ }
complex-matrix = element complex-matrix { matrix_attlist, mat_complex+ }
variant-matrix =
  element variant-matrix {
    matrix_attlist, (mat_number | mat_string | mat_complex)+
  }
cpx = xsd:string { pattern = "[\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?[\-+][0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?i" }
key_or_ikey =
  attribute key { text }
  | attribute ikey { xsd:double }
row_cols =
  attribute rows { xsd:positiveInteger },
  attribute cols { xsd:positiveInteger }
matrix_attlist = key_or_ikey, row_cols

Binärformat

header: "USO" version-number
object: 'o' len ikey id-or-ref
object: 'p' len key id-or-ref
endofobj: ')'

double: 'n' ikey data
double: 'm' key data
string: 's' ikey string
string: 't' key string
complex: 'c' ikey cdata
complex: 'd' key cdata

matrix: 'N' len ikey shape data
matrix: 'M' len key shape data
smatrix: 'S' len ikey shape string
smatrix: 'T' len key shape string
cmatrix: 'C' len ikey shape cdata
cmatrix: 'D' len key shape cdata
vmatrix: 'V' len ikey shape vdata
vmatrix: 'W' len key shape vdata

Alle Werte werden in Little-Endian byte order (LEBO) gespeichert.

Dem Header (4 Bytes) folgt ein Objekt ‚o‘ mit der ID=1 und dem ikey=0.0. Dem Objekt folgen beliebig viele Objekte oder andere Datenelemente. Jedes Objekt wird mit einem endofobj: ‚)‘ beendet.

version-number byte, diese Version hat die Nummer 1.
len Alle Matrizen und Objekte haben hinter dem Tag die Länge des Elementes als 64-Bit Integer gespeichert.
ikey Zahlenkey (double - 8 Bytes).
key keylen (int32) in Bytes, gefolgt beliebig vielen UTF-16-Zeichen. In keys sind beliebige UNICODE-Zeichen erlaubt, aber keine null-Zeichen.
id_or_ref (int32), ID des Objekts (1, 2, …) oder, falls id_or_ref eine negative Zahl ist, Referenz auf ein anderes Objekt.
shape nrows (int32) ncols (int32). Anzahl an Zeilen und Spalten einer Matrix. Die Elemente der Matrix werden spaltenweise gespeichert: a[1;1], a[2;1], …
string len (int32) in Bytes, gefolgt von UTF-16-Zeichen oder beliebigen Bytes (auch 0-Bytes).
data Matrix mit Zahlen (double - 8 Bytes). Falls nicht das Format "uncompressed-binary" angegeben wurde, werden die Daten als ein Block mit LZ4 komprimiert (https://code.google.com/p/lz4/). Falls len gleich nrows*ncols*8 ist, sind die Daten unkomprimiert. In dieser Version werden nur data-Elemente (Zahlenmatrizen) komprimiert. Stringmatrizen, Matrizen mit komplexen Werten, Variantmatrizen und Objekte werden nicht komprimiert.
cdata Matrix mit komplexen Elementen (jeweils zwei double-Werte: real, imag).
vdata Variantmatrix. Elemente können Zahl, komplexe Zahl, String oder Objekt sein. Vor den Daten steht jeweils ein Kennbyte: ‚n‘, ‚c‘, ‚s‘, ‚o‘.

Zyklische Referenzen

Die Funktion kann auch Objekte speichern, die zyklische Referenzen enthalten, z. B.

obj = obj_create()
obj.val = 123
obj.next = obj_create()
obj.next.val = 456
obj.next.next = obj
obj.save("d:\\test1.xml")

erzeugt folgende Datei (beachte Attribute id und ref):

<?xml version='1.0' encoding='utf-8'?>
<obj id='1'>
    <obj id='2' key='next'>
        <obj key='next' ref='1'/>
        <number key='val'>456</number>
    </obj>
    <number key='val'>123</number>
</obj>

History

Version Beschreibung
R2014.3 Objekte können nun auch in einem Binärformat gespeichert werden.
5.10.0 Für den Dateinamen kann ein leerer String angegeben werden, um das Objekt in einem String anstatt einer Datei zu speichern.
5.0.0 Unicode-Änderungen.
4.1.0 Neu.

id-699932