Lesen und Schreiben von ByteArraysFlash Player 9 und höher, Adobe AIR 1.0 und höher Die ByteArray-Klasse ist Teil des Pakets flash.utils. Erstellen Sie ein ByteArray-Objekt in ActionScript 3.0, indem Sie wie im folgenden Beispiel dargestellt die ByteArray-Klasse importieren und den Konstruktur aufrufen: import flash.utils.ByteArray; var stream:ByteArray = new ByteArray(); ByteArray-MethodenJeder aussagekräftige Datenstrom ist in einem Format angeordnet, das Sie analysieren können, um die gewünschten Informationen zu finden. Ein Datensatz in einer einfachen Arbeitnehmerdatei enthält zum Beispiel in der Regel eine Kennnummer, einen Namen, eine Adresse, eine Telefonnummer und weitere Daten. Eine MP3-Audiodatei enthält einen ID3-Tag, der Titel, Autor, Album, Veröffentlichungsdatum und Genre der herunterzuladenden Datei angibt. Anhand des Formats wissen Sie, in welcher Reihenfolge Sie die Daten im Datenstrom zu erwarten haben. So können Sie den Bytestrom intelligent lesen. Die ByteArray-Klasse umfasst mehrere Methoden, die das Lesen von und Schreiben in einem Datenstrom erleichtern. Zu diesen Methoden gehören readBytes() und writeBytes(), readInt() und writeInt(), readFloat() und writeFloat(), readObject() und writeObject() und readUTFBytes() und writeUTFBytes(). Mit diesen Methoden können Sie Daten vom Datenstrom in Variablen bestimmter Datentypen lesen und von bestimmten Datentypen direkt in den binären Datenstrom schreiben. Der folgende Code liest zum Beispiel ein einfaches Array von Strings und Gleitkommazahlen und schreibt jedes Element in ein ByteArray. Der Aufbau des Arrays erlaubt es dem Code, die entsprechende ByteArray-Methode aufzurufen (writeUTFBytes() und writeFloat()), um die Daten zu schreiben. Aufgrund des sich wiederholenden Datenmusters kann das Array mit einer Schleife gelesen werden. // The following example reads a simple Array (groceries), made up of strings
// and floating-point numbers, and writes it to a ByteArray.
import flash.utils.ByteArray;
// define the grocery list Array
var groceries:Array = ["milk", 4.50, "soup", 1.79, "eggs", 3.19, "bread" , 2.35]
// define the ByteArray
var bytes:ByteArray = new ByteArray();
// for each item in the array
for (var i:int = 0; i < groceries.length; i++) {
bytes.writeUTFBytes(groceries[i++]); //write the string and position to the next item
bytes.writeFloat(groceries[i]); // write the float
trace("bytes.position is: " + bytes.position); //display the position in ByteArray
}
trace("bytes length is: " + bytes.length); // display the length
Die Eigenschaft „position“Mit der Eigenschaft „position“ wird die aktuelle Position des Zeigers gespeichert, der das ByteArray während des Lese- oder Schreibvorgangs indiziert. Der Anfangswert der Eigenschaft ist wie im folgenden Code dargestellt 0 (Null): var bytes:ByteArray = new ByteArray();
trace("bytes.position is initially: " + bytes.position); // 0
Wenn Sie von einem ByteArray lesen oder in es schreiben, aktualisiert die verwendete Methode die Eigenschaft „position“ so, dass sie auf die Stelle direkt hinter dem letzten Byte verweist, das gelesen oder geschrieben wurde. Der folgende Code schreibt zum Beispiel einen String in ein ByteArray und die Eigenschaft „position“ verweist danach auf das Byte direkt nach dem String im ByteArray: var bytes:ByteArray = new ByteArray();
trace("bytes.position is initially: " + bytes.position); // 0
bytes.writeUTFBytes("Hello World!");
trace("bytes.position is now: " + bytes.position); // 12
Bei einem Lesevorgang wird die Eigenschaft „position“ ebenfalls um die Anzahl der gelesenen Byte erhöht. var bytes:ByteArray = new ByteArray();
trace("bytes.position is initially: " + bytes.position); // 0
bytes.writeUTFBytes("Hello World!");
trace("bytes.position is now: " + bytes.position); // 12
bytes.position = 0;
trace("The first 6 bytes are: " + (bytes.readUTFBytes(6))); //Hello
trace("And the next 6 bytes are: " + (bytes.readUTFBytes(6))); // World!
Beachten Sie, dass Sie die Eigenschaft „position“ auf eine bestimmte Stelle im ByteArray setzen können, um ab dieser Stelle zu lesen oder zu schreiben. Die Eigenschaften „bytesAvailable“ und „length“Die Eigenschaften length und bytesAvailable geben an, wie lang ein ByteArray ist und wie viele Byte ab der aktuellen Position bis zum Ende verbleiben. Im folgenden Beispiel wird gezeigt, wie Sie diese Eigenschaften einsetzen können. Im Beispiel wird ein Textstring in das ByteArray geschrieben und das ByteArray dann Byte für Byte gelesen, bis der Buchstabe „a“ oder das Ende erreicht wird (bytesAvailable <= 0). var bytes:ByteArray = new ByteArray();
var text:String = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus etc.";
bytes.writeUTFBytes(text); // write the text to the ByteArray
trace("The length of the ByteArray is: " + bytes.length); // 70
bytes.position = 0; // reset position
while (bytes.bytesAvailable > 0 && (bytes.readUTFBytes(1) != 'a')) {
//read to letter a or end of bytes
}
if (bytes.position < bytes.bytesAvailable) {
trace("Found the letter a; position is: " + bytes.position); // 23
trace("and the number of bytes available is: " + bytes.bytesAvailable); // 47
}
Die Eigenschaft „endian“Verschiedene Computer verwenden verschiedene Verfahren für das Speichern aus mehreren Byte bestehender Zahlen, also Zahlen, die mehr als ein Byte Speicherplatz benötigen. Eine Ganzzahl kann beispielsweise 4 Byte, oder 32 Bit, Speicherplatz beanspruchen. Einige Computer speichern das höchstwertigste Byte der Zahl zuerst, an der niedrigsten Speicheraddresse, andere Computer speichern das niedrigwertigste Byte zuerst. Dieses Attribut der Computer, die Byte-Reihenfolge, wird als big endian (höchstwertigstes Byte zuerst) oder little endian (niedrigwertigstes Byte zuerst) bezeichnet. Die Zahl 0x31323334 wird nach den Systemen big endian und little endian wie folgt gespeichert, wobei a0 für die niedrigste Speicheradresse der 4 Byte steht und a3 für die höchste:
Mit der Eigenschaft endian der ByteArray-Klasse können Sie diese Byte-Reihenfolge für aus mehreren Byte bestehende Zahlen, die Sie verarbeiten, angeben. Die anerkannten Werte für diese Eigenschaft lauten entweder „bigEndian" oder „littleEndian" und die Endian-Klasse definiert die Konstanten BIG_ENDIAN und LITTLE_ENDIAN für die Einstellung der Eigenschaft endian mit diesen Strings. Die Methoden „compress()“ und „uncompress()“Mit der Methode compress() können Sie ein ByteArray entsprechend eines als Parameter angegebenen Komprimierungsalgorithmus komprimieren. Mit der Methode uncompress() dagegen können Sie ein komprimiertes ByteArray entsprechend eines als Parameter angegebenen Komprimierungsalgorithmus dekomprimieren. Nach Aufruf von compress() und uncompress() werden die Länge des Byte-Arrays auf die neue Länge und die Eigenschaft „position“ auf das Ende gesetzt. Die CompressionAlgorithm-Klasse (AIR) definiert Konstanten, mit denen Sie den Komprimierungsalgorithmus angeben können. Die ByteArray-Klasse unterstützt sowohl den deflate-Algorithmus (nur AIR) als auch den zlib-Algorithmus. Der Komprimierungsalgorithmus „deflate“ wird in verschiedenen Komprimierungsformaten wie zlib, gzip und einigen zip-Implementationen verwendet. Eine Beschreibung des komprimierten Datenformats „zlib“ finden Sie unter http://www.ietf.org/rfc/rfc1950.txt, eine Beschreibung des Komprimierungsalgorithmus „deflate“ unter http://www.ietf.org/rfc/rfc1951.txt. Im folgenden Beispiel wird ein ByteArray mit dem Namen bytes mithilfe des Algorithmus „deflate“ komprimiert: bytes.compress(CompressionAlgorithm.DEFLATE); Im folgenden Beispiel wird ein komprimiertes ByteArray mit dem Algorithmus „deflate“ dekomprimiert: bytes.uncompress(CompressionAlgorithm.DEFLATE); Lesen und Schreiben von ObjektenDie Methoden readObject() und writeObject() lesen ein Objekt aus und schreiben es im serialisierten Action Message Format (AMF) in ein ByteArray. AMF ist ein herstellerspezifisches Meldungsprotokoll von Adobe, das in verschiedenen ActionScript 3.0-Klassen, einschließlich Netstream, NetConnection, NetStream, LocalConnection und Shared Objects, eingesetzt wird. Eine aus einem Byte bestehende Markierung gibt den Typ der kodierten Daten an, die folgen. AMF verwendet die folgenden 13 Datentypen: value-type = undefined-marker | null-marker | false-marker | true-marker | integer-type |
double-type | string-type | xml-doc-type | date-type | array-type | object-type |
xml-type | byte-array-type
Die kodierten Daten folgen der Typmarkierung, es sei denn, die Markierung steht für einen einzigen möglichen Wert, wie null, true oder false. In diesem Fall sind sonst keine Daten kodiert. Es stehen zwei AMF-Versionen zur Verfügung: AMF 0 und AMF 3. AMF 0 unterstützt die Sendung komplexer Objekte durch Referenzen und lässt die Wiederherstellung von Objektbeziehungen durch Endpunkte zu. AMF 3 stellt gegenüber AMF 0 eine Verbesserung dar, da zusätzlich zu den Objektverweisen Objektmerkmale und Strings durch Referenzen gesendet werden können und in ActionScript 3.0 eingeführte neue Datentypen unterstützt werden. Die Eigenschaft ByteArray.objectEcoding gibt die AMF-Version an, die zur Kodierung der Objektdaten verwendet wird. Die Klasse flash.net.ObjectEncoding legt die Konstanten für die Angabe der AMF-Version fest: ObjectEncoding.AMF0 und ObjectEncoding.AMF3. Im folgenden Beispiel wird writeObject() aufgerufen, um ein XML-Objekt in ein ByteArray zu schreiben. Dieses wird dann mit dem deflate-Algorithmus komprimiert und in die Datei order auf dem Desktop geschrieben. Nach Abschluss des Vorgangs wird im AIR-Fenster die Meldung „Wrote order file to desktop!“ eingeblendet. /* The following lines, minus comment characters
, are for Flex version:
* <?xml version="1.0" encoding="utf-8"?>
* <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
* creationComplete="init();">
* <mx:Script>
* <![CDATA[
*/
import flash.filesystem.*;
import flash.utils.ByteArray;
// import mx.controls.Label for Flex
import fl.controls.Label // for Flash; Label component must be in Library
// for Flex: private function init():void {
var bytes:ByteArray = new ByteArray();
var myLabel:Label = new Label();
myLabel.move(150, 150);
myLabel.width = 200;
addChild(myLabel);
var myXML:XML =
<order>
<item id='1'>
<menuName>burger</menuName>
<price>3.95</price>
</item>
<item id='2'>
<menuName>fries</menuName>
<price>1.45</price>
</item>
</order>
// Write XML object to ByteArray
bytes.writeObject(myXML);
bytes.position = 0; //reset position to beginning
bytes.compress(CompressionAlgorithm.DEFLATE); // compress ByteArray
outFile("order", bytes);
myLabel.text = "Wrote order file to desktop!";
// for Flex: } // end of init()function outFile(fileName:String, data:ByteArray):void {
var outFile:File = File.desktopDirectory; // dest folder is desktop
outFile = outFile.resolvePath(fileName); // name of file to write
var outStream:FileStream = new FileStream();
// open output file stream in WRITE mode
outStream.open(outFile, FileMode.WRITE);
// write out the file
outStream.writeBytes(data, 0, data.length);
// close it
outStream.close();
}
/* Add the following lines for Flex, minus comment characters:
* ]]>
* </mx:Script>
* </mx:WindowedApplication>
*/
Die Methode readObject() liest ein Objekt im serialisierten AMF aus dem ByteArray und speichert es in einem Objekt des angegebenen Typs. Im folgenden Beispiel wird die Datei order aus dem Desktop in ein ByteArray (inBytes) gelesen, dekomprimiert und es wird readObject() aufgerufen, um die Daten im XML-Objekt orderXML zu speichern. Es wird das Schleifenkonstrukt for each() verwendet, um jeden Knoten für die Anzeige zu einem Textbereich hinzuzufügen. Das Beispiel zeigt auch den Wert der Eigenschaft objectEncoding sowie einen Header für die Inhalte der Datei order an. /* The following lines, minus comment characters, are for Flex version:
* <?xml version="1.0" encoding="utf-8"?>
* <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
* creationComplete="init();">
* <mx:Script>
* <![CDATA[
*/
import flash.filesystem.*;
import flash.utils.ByteArray; import fl.controls.TextArea; // in Flash, TextArea component must be in Library
// for Flex version: import mx.controls;
// for Flex version: private function init():void { var inBytes:ByteArray = new ByteArray();
// define text area for displaying XML content
var myTxt:TextArea = new TextArea();
myTxt.width = 550;
myTxt.height = 400;
addChild(myTxt);
//display objectEncoding and file heading
myTxt.text = "Object encoding is: " + inBytes.objectEncoding + "\n\n" + "order file: \n\n";
readFile("order", inBytes);
inBytes.position = 0; // reset position to beginning
inBytes.uncompress(CompressionAlgorithm.DEFLATE);
inBytes.position = 0; //reset position to beginning
// read XML Object
var orderXML:XML = inBytes.readObject();
//for each node in orderXML
for each(var child:XML in orderXML) {
// append child node to text area
myTxt.text += child + "\n";
}
// for Flex version: } // end of init() // read specified file into byte array
function readFile(fileName:String, data:ByteArray) {
var inFile:File = File.desktopDirectory; // source folder is desktop
inFile = inFile.resolvePath(fileName); // name of file to read
var inStream:FileStream = new FileStream();
inStream.open(inFile, FileMode.READ);
inStream.readBytes(data, 0, data.length);
inStream.close();
}
/* Add the following lines, minus comment characters, for Flex:
* ]]>
* </mx:Script>
*
* </mx:WindowedApplication>
*/
|
|