Läsa och skriva en ByteArrayFlash Player 9 och senare, Adobe AIR 1.0 och senare Klassen ByteArray tillhör paketet flash.utils. Om du vill skapa ett ByteArray-objekt i ActionScript 3.0 importerar du klassen ByteArray och anropar konstruktorn, vilket visas i exemplet nedan: import flash.utils.ByteArray; var stream:ByteArray = new ByteArray(); ByteArray-metoderAlla meningsfulla dataströmmar ordnas i ett format som du kan analysera så att du hittar den information du vill ha. I en post i en enkel anställningsfil tar du till exempel med ID-nummer, namn, adress, telefonnummer och så vidare. En MP3-ljudfil innehåller en ID3-tagg som identifierar titel, författare, album, publiceringsdatum och genre för filen som hämtas. Det här formatet gör att du vet i vilken ordning som data i strömmen förväntas. Du kan läsa byteströmmen på ett effektivt sätt. Klassen ByteArray omfattar flera metoder som gör det enklare att läsa från och skriva till en dataström. En del av dessa metoder omfattar readBytes() och writeBytes(), readInt() och writeInt(), readFloat() och writeFloat(), readObject() och writeObject() samt readUTFBytes() och writeUTFBytes(). Med dessa metoder kan du läsa data från dataströmmen till variabler med särskilda datatyper och skriva från särskilda datatyper direkt i den binära dataströmmen. Följande kod läser en enkel array med strängar och flyttal och skriver respektive element till en ByteArray. Strukturen på arrayen gör det möjligt för koden att anropa lämpliga ByteArray-metoder (writeUTFBytes() och writeFloat()) för att skriva data. Det återkommande datamönstret gör det möjligt att läsa arrayen med en slinga. // 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 Egenskapen positionEgenskapen position lagrar den aktuella positionen för pekaren som indexerar ByteArray vid läsning eller skrivning. Startvärdet för egenskapen position är 0 (noll) vilket visas i koden nedan: var bytes:ByteArray = new ByteArray(); trace("bytes.position is initially: " + bytes.position); // 0 När du läser från eller skriver till en ByteArray uppdaterar metoder som du använder egenskapen position till att peka på platsen omedelbart efter den sista byte som lästes eller skrevs. I följande kod skrivs en sträng till en ByteArray och sedan pekar egenskapen position mot den byte som finns omedelbart efter strängen i 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 En läsåtgärd ökar på samma sätt egenskapen position med det antal byte som läses. 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! Observera att du kan ange egenskapen position till en plats i en ByteArray om du vill läsa eller skriva vid den förskjutningen. Egenskaperna bytesAvailable och lengthEgenskaperna length och bytesAvailable anger hur lång en ByteArray är och hur många byte som finns kvar i den från den aktuella positionen till slutet. I följande exempel visas hur du kan använda dessa egenskaper. I exemplet skrivs en sträng med text till en ByteArray och sedan läses denna ByteArray med en byte i taget tills tecknet ”a” eller slutet (bytesAvailable <= 0) påträffas. 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 } Egenskapen endianOlika datorer kan lagra multibytetal på olika sätt, vilket innebär att tal kanske kräver mer än en byte med minne för att lagras. Ett heltal kanske till exempel behöver fyra byte, eller 32 bitar, med minne. Vissa datorer lagrar den mest signifikanta byten i siffran först, i den lägsta minnesadressen, och andra lagrar den minst signifikanta byten först. Denna byteordning kallas för big endian (mest signifikanta byte först) eller little endian (minst signifikanta byte först). Talet 0x31323334 skulle till exempel lagras på följande sätt med byteordningen big endian respektive little endian, där a0 representerar den lägsta minnesdressen på fyra byte och a3 representerar den högsta:
Med egenskapen endian för klassen ByteArray kan du ange denna byteordning för multibytetal som du bearbetar. Godkända värden för den här egenskapen är "bigEndian" och "littleEndian" och klassen Endian definierar konstanterna BIG_ENDIAN och LITTLE_ENDIAN när egenskapen endian ställs in med dessa strängar. Metoderna compress() och uncompress()Med metoden compress() kan du komprimera en ByteArray enligt en komprimeringsalgoritm som du anger som en parameter. Med metoden uncompress() kan du dekomprimera en komprimerad ByteArray enligt en komprimeringsalgoritm. När du har anropat compress() och uncompress() ställs längden på bytearrayen in på den nya längden och egenskapen position ställs in på slutet. Klassen CompressionAlgorithm (AIR) definierar konstanter, som du kan använda för att ange komprimeringsalgoritmen. Klassen ByteArray har stöd för algoritmerna deflate (endast AIR) och zlib. Dekomprimeringsalgoritmen används i flera komprimeringsformat, till exempel zlib, gzip och en del zip-implementationer. Zlib-komprimerade dataformat beskrivs på http://www.ietf.org/rfc/rfc1950.txt och dekomprimeringsalgoritmen beskrivs på http://www.ietf.org/rfc/rfc1951.txt. I följande exempel komprimeras en ByteArray med namnet bytes som använder dekomprimeringsalgoritmen: bytes.compress(CompressionAlgorithm.DEFLATE); I följande exempel dekomprimeras en komprimerad ByteArray som använder dekomprimeringsalgoritmen: bytes.uncompress(CompressionAlgorithm.DEFLATE); Läsa och skriva objektMetoderna readObject() och writeObject() kan läsa ett objekt från och skriva ett objekt till en ByteArray, kodad med AMF-serialisering (Action Message Format). AMF är ett tillverkarspecifikt meddelandeprotokoll som har skapats av Adobe och används av olika ActionScript 3.0-klasser, bland annat Netstream, NetConnection, NetStream, LocalConnection och Shared Objects. En typmarkör på en byte beskriver vilken typ av kodade data som följer. AMF använder följande 13 datatyper: 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 Den kodade datan kommer efter typmarkören såvida inte markören representerar ett enda möjligt värde, till exempel null eller sant eller falskt. Då kodas inget annat. Det finns två versioner av AMF: AMF0 och AMF3. AMF 0 har stöd för att skicka komplexa objekt via referens och tillåter slutpunkter att återställa objektrelationer. AMF 3 förbättrar AMF 0 genom att skicka objekt-traits och strängar via referens, förutom objektreferenserna, och genom att ha stöd för de nya datatyper som introducerades i ActionScript 3.0. Egenskapen ByteArray.objectEcoding anger vilken version av AMF som används för att koda objektdata. Klassen flash.net.ObjectEncoding definierar konstanter som anger AMF-versionen: ObjectEncoding.AMF0 och ObjectEncoding.AMF3. Följande exempel anropar writeObject() för att skriva ett XML-objekt till en ByteArray. Sedan komprimeras objektet med hjälp av dekomprimeringsalgoritmen och skrivs till filen order på skrivbordet. I exemplet används en etikett för att visa meddelandet ”Wrote order file to desktop!” i AIR-fönstret när det är klart. /* 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> */ Metoden readObject() läser ett objekt i serialiserat AMF från en ByteArray och lagrar det i ett objekt av angiven typ. I följande exempel läser filen order från skrivbordet till en ByteArray (inBytes), dekomprimerar den och anropar readObject() för att lagra den i XML-objektet orderXML. I exemplet används en for each()-slingakonstruktor för att lägga till varje nod i ett textområde så att de visas. I exemplet visas också värdet på egenskapen objectEncoding tillsammans med huvudet för innehållet i filen 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> */ |
|