.. highlightlang:: us
.. index:: obj_save
.. _obj_save:
obj_save
========
.. us.tag obj_save NOTREADYGERMAN obj New410 Changed500 Changed5100 Changed5500 Changed5603
:ref:`obj_save` speichert ein Objekt in einer Datei oder in einer Zeichenkette
als XML-Datei oder Binärdatei.
.. function:: ret = obj_save(obj, ssFilename)
ret = obj_save(obj, ssFilename, ssFormat)
ssXMLString = obj_save(obj, "")
.. us.return
**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.
.. us.params
**Parameter**
.. uparam:: obj
*obj* ist ein mit :ref:`obj_create` erzeugtes Objekt.
.. uparam:: ssFilename
*ssFilename* ist der komplette Dateiname oder ein leerer String (``""``)
(siehe *ret*).
.. uparam:: ssFormat
*ssFormat* ist entweder ein Format-String der angibt, wie Zahlen gespeichert
werden sollen (siehe :ref:`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.
.. us.example
**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:
.. highlightlang:: xml
::
123
Hello
456
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)
.. us.comment
**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):
.. relax
::
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
.. relax-end
**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.
.. list-table::
:header-rows: 0
* - 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.
.. highlightlang:: us
::
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``):
.. highlightlang:: xml
::
456
123
.. us.history
**History**
.. list-table::
:header-rows: 1
* - 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.
.. seealso::
:ref:`uberblick-uniscript-objekte`,
:ref:`obj_load`,
:ref:`obj_copy`
:sub:`id-699932`