Odczytywanie i zapisywanie obiektu ByteArrayFlash Player 9 i nowsze wersje, Adobe AIR 1.0 i nowsze wersje Klasa ByteArray należy do pakietu flash.utils. Aby utworzyć obiekt ByteArray w programie ActionScript 3.0, należy zaimportować klasę ByteArray i wywołać konstruktora zgodnie z następującym przykładem: import flash.utils.ByteArray; var stream:ByteArray = new ByteArray(); ByteArray, metodyKażdy poprawny strumień danych jest uporządkowany w formacie, który można analizować w celu wyszukania żądanych informacji. Rekord w prostym pliku pracownika może na przykład zawierać imię i nazwisko, numer dowodu osobistego, adres, numer telefonu, itd. Plik audio MP3 zawiera znacznik ID3 określający autora, album, datę publikacji oraz gatunek pobieranego pliku. Format pozwala na określenie kolejności danych w strumieniu danych. Umożliwia również inteligentne odczytanie strumienia bajtów. Klasa ByteArray zawiera kilka metod ułatwiających odczytywanie i zapisywanie danych do strumienia danych. Niektóre z tych metod zawierają readBytes() i writeBytes(), readInt() i writeInt(), readFloat() i writeFloat(), readObject() i writeObject(), oraz readUTFBytes() i writeUTFBytes(). Te metody umożliwiają odczytanie danych ze strumienia danych jako zmienne określonych typów danych i zapisanie określonych typów danych bezpośrednio do binarnego strumienia danych. Na przykład, następujący kod odczytuje prostą tablicę ciągów i liczby zmiennoprzecinkowe i zapisuje każdy element do ByteArray. Organizacja tablic umożliwia kodowi wywołanie odpowiedniej metody ByteArray (writeUTFBytes() i writeFloat()) w celu zapisania danych. Powtarzający się wzór danych umożliwia odczytanie tablicy w pętli. // 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
Właściwość positionWłaściwość position zapisuje bieżącą pozycję wskaźnika indeksującego obiekt ByteArray podczas odczytywania i zapisywania. Początkowa wartość właściwości position to 0 (zero) zgodnie z następującym kodem: var bytes:ByteArray = new ByteArray();
trace("bytes.position is initially: " + bytes.position); // 0
Podczas odczytywania i zapisywania do obiektu ByteArray użyte metody aktualizują właściwość position, tak aby wskazywała miejsce bezpośrednio po ostatnim zapisanym lub odczytanym bajcie. Na przykład, następujący kod zapisuje ciąg w obiekcie ByteArray, a następnie właściwość position wskazuje bajt bezpośrednio po łańcuchu w obiekcie 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
Podobnie, czynność odczytywania powoduje zwiększanie wartości właściwości position o liczbę odczytanych bajtów. 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!
Właściwość position można ustawić na określone położenie w obiekcie ByteArray w celu odczytania lub zapisania przy tym przesunięciu. Właściwości bytesAvailable i lengthWłaściwości length i bytesAvailable informują o długości obiektu ByteArray oraz liczbie znajdujących się w nim bajtów od położenia początkowego od końca. W następującym przykładzie przedstawiony jest sposób użycia tych właściwości. W przykładzie w obiekcie ByteArray zapisany jest ciąg tekstu String, który jest następnie odczytany jako kolejne bajty do czasu napotkania znaku „a” lub zakończenia (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
}
Właściwość endianKomputery mogą różnić się w sposobie zapisywania liczb wielobajtowych, tj. liczb wymagających do zapisania więcej niż jeden bajt pamięci. Liczba całkowita może na przykład zajmować w pamięci 4 bajty lub 32 bity. Niektóre komputery zapisują w pierwszej kolejności najbardziej znaczące bajty w najniższych adresach pamięci, inne natomiast najmniej znaczące bajty. Ten atrybut komputera lub kolejność bajtów określa się jako big endian (najbardziej znaczące bajty najpierw) lub little endian (najmniej znaczące bajty najpierw). Na przykład, liczba 0x31323334 będzie zapisana w następujący sposób zgodnie z kolejnością bajtów big endian i little endian, gdzie a0 przedstawia najniższy adres pamięci 4 bajtów, a a3 przedstawia najwyższy:
Właściwość endian klasy ByteArray umożliwia określenie kolejności bajtów dla przetwarzanych liczb wielobajtowych. Dopuszczalne wartości to "bigEndian" lub "littleEndian" - klasa Endian definiuje stałe BIG_ENDIAN i LITTLE_ENDIAN do ustawienia wartości endian za pomocą tych ciągów. Metody compress() i uncompress()Metoda compress() umożliwia kompresje obiektu ByteArray zgodnie z algorytmem kompresji określonego jako parametr. Metoda uncompress() umożliwia cofnięcie kompresji skompresowanego ByteArray zgodnie z algorytmem kompresji. Po wywołaniu metody compress() i uncompress() dla długości tablicy bajtów zostaje ustawiona nowa długość, a właściwość position zostaje ustawiona na koniec. Klasa CompressionAlgorithm (AIR) definiuje stałe, które można używać w celu określenia algorytmu kompresji. Klasa ByteArray obsługuje zarówno algorytm deflate (tylko w środowisku AIR), jak i zlib. Algorytm kompresji deflate można stosować w wielu formatach kompresji np. zlib, gzip i wybranych implementacjach zip. Format danych skompresowanych zlib został opisany pod adresemhttp://www.ietf.org/rfc/rfc1950.txt, a algorytm kompresji deflate opisany jest pod adresem http://www.ietf.org/rfc/rfc1951.txt. W następującym przykładzie skompresowany jest obiekt ByteArray o nazwie bytes za pomocą algorytmu deflate: bytes.compress(CompressionAlgorithm.DEFLATE); W następującym przykładzie anulowana jest kompresja skompresowanego obiektu ByteArray za pomocą algorytmu deflate: bytes.uncompress(CompressionAlgorithm.DEFLATE); Odczytywanie i zapisywanie obiektówMetody readObject() i writeObject() odczytują obiekt i zapisują go do obiektu ByteArray zakodowanego w serializowanym formacie AMF (Action Message Format). Format AMF to protokół z informacjami na temat praw własności utworzony przez Adobe i stosowany przez różne klasy ActionScript 3.0, w tym Netstream, NetConnection, NetStream, LocalConnection oraz Shared Objects. Znacznik jednobajtowy opisuje typ zakodowanych danych występujących po nim. Format AMF korzysta z następujących 13 typów danych: 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
Zakodowane dane występują po typie znacznika, chyba że znacznik przedstawia pojedynczą dopuszczalną wartość, np. null lub true bądź false. W takim wypadku nie są kodowane żadne inne dane. Istnieją dwie wersje formatu AMF: AMF0 i AMF3. AMF 0 obsługuje wysyłanie złożonych obiektów poprzez odniesienie i umożliwia punktom końcowym przywrócenie relacji pomiędzy obiektami. AMF 3 uzupełnia AMF 0 poprzez przesłanie cech i ciągów jako odniesienie oprócz odniesienia do obiektów oraz poprzez obsługę nowych typów danych wprowadzonych w ActionScript 3.0. Właściwość ByteArray.objectEcodingokreśla wersję pliku AMF użytego w celu zakodowania danych obiektu. Klasa flash.net.ObjectEncoding określa stałe w celu określenia wersji AMF: ObjectEncoding.AMF0 i ObjectEncoding.AMF3. W następującym przykładzie wywołana jest metoda writeObject() w celu zapisania obiektu XML do obiektu ByteArray, który zostaje następnie skompresowany za pomocą algorytmu Deflate i zapisany do pliku order na pulpicie. W przykładzie wykorzystana jest etykieta w celu wyświetlenia komunikatu „Wrote order file to desktop!” w oknie AIR po zakończeniu czynności. /* 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>
*/
Metoda readObject() odczytuje obiekt w serializowanym formacie AMF z obiektu ByteArray i zapisuje go w obiekcie określonego typu. W następującym przykładzie odczytany jest plik order z pulpitu do obiektu ByteArray (inBytes), cofnięta zostanie kompresja i wywołana metoda readObject() w celu zapisania pliku w obiekcie XML orderXML. W tym przykładzie wykorzystana jest pętla for each() w celu dodania każdego węzła do obszaru tekstowego do wyświetlenia. W tym przykładzie wyświetlona jest również wartość właściwości objectEncoding razem z nagłówkiem treści w pliku order. /* 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>
*/
|
|