Ler e escrever um ByteArrayFlash Player 9 e posterior, Adobe AIR 1.0 e posterior A classe ByteArray é parte do pacote flash.utils. Para criar um objeto ByteArray no ActionScript 3.0, importe a classe ByteArray e invoque o construtor, conforme exibido no seguinte exemplo: import flash.utils.ByteArray; var stream:ByteArray = new ByteArray(); Métodos ByteArrayQualquer fluxo de dados significativo é organizado em um formato que você pode analisar para encontrar as informações desejadas. Um registro em um simples arquivo de um funcionário, por exemplo, provavelmente incluiria um número de ID, um nome, um endereço, um número de telefone e assim por diante. Um arquivo de áudio MP3 contém uma marca ID3 que identifica o título, autor, álbum, data de publicação e gênero do arquivo que está sendo obtido por download. O formato permite que você saiba a ordem na qual esperar os dados no fluxo de dados. Ele permite que você leia o fluxo de bytes de modo inteligente. A classe ByteArray inclui vários métodos que facilitam ler de e escrever para um fluxo de dados. Alguns desses métodos incluem readBytes() e writeBytes(), readInt() e writeInt(), readFloat() e writeFloat(), readObject() e writeObject() e readUTFBytes() e writeUTFBytes(). Esses métodos permitem que você leia dados do fluxo de dados em variáveis de tipos de dados específicos e escreva de tipos de dados específicos diretamente para o fluxo de dados binário. Por exemplo, o código a seguir lê uma matriz simples de seqüências de caracteres e números de ponto flutuante e escreve cada elemento em um ByteArray. A organização da matriz permite que o código chame os métodos ByteArray apropriados (writeUTFBytes() e writeFloat()) para escrever os dados. O padrão de dados repetitivo possibilita ler a matriz com um loop. // 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 A propriedade positionA propriedade position armazena a posição atual do ponteiro que indexa ByteArray durante a leitura ou escrita. O valor inicial da propriedade position é 0 (zero), como exibido no seguinte código: var bytes:ByteArray = new ByteArray(); trace("bytes.position is initially: " + bytes.position); // 0 Quando você lê de ou escreve em um ByteArray, o método usado atualiza a propriedade position para apontar para o local imediatamente seguindo o último byte lido ou escrito. Por exemplo, o código a seguir escreve uma seqüência de caracteres em um ByteArray e, posteriormente, a propriedade position aponta para o byte imediatamente seguindo a seqüência de caracteres no 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 Da mesma forma, uma operação de leitura incrementa a propriedade position pelo número de bytes lidos. 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! Observe que você pode definir a propriedade position para um local específico no ByteArray para ler ou escrever naquele deslocamento. As propriedades bytesAvailable e lengthAs propriedades length e bytesAvailable dizem a você quanto tempo um ByteArray possui e quantos bytes permanecem nele da posição atual até o fim. O exemplo a seguir ilustra como você pode usar essas propriedades. O exemplo escreve uma seqüência de caracteres de texto para o ByteArray e, em seguida, lê um byte de cada vez do ByteArray até que ele encontre o caractere “a” ou o final (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 } A propriedade endianOs computadores podem diferir em como armazenam números de vários bytes, isto é, números que exigem mais de um 1 byte de memória para armazená-los. Um inteiro, por exemplo, pode levar 4 bytes, ou 32 bits, de memória. Alguns computadores armazenam o byte mais significativo do número primeiro, no endereço de memória mais baixo e outros armazenam o byte menos significativo primeiro. Esse atributo de um computador, ou de uma ordem de bytes, é conhecido como sendo big endian (byte mais significativo primeiro) ou little endian (byte menos significativo primeiro). Por exemplo, o número 0x31323334 seria armazenado da seguinte forma para ordem de bytes big endian e little endian, onde a0 representa o endereço de memória mais baixo dos 4 bytes e a3 representa o mais alto:
A propriedade endian da classe ByteArray permite que você denote essa ordem de bytes para números de vários bytes que você esteja processando. Os valores aceitáveis para essa propriedade são "bigEndian" ou "littleEndian" e a classe Endian define as constantes BIG_ENDIAN e LITTLE_ENDIAN para definir a propriedade endian com essas seqüências de caracteres. Os métodos compress() e uncompress()O método compress() permite que você compacte um ByteArray de acordo com um algoritmo de compactação especificado como um parâmetro. O método uncompress() permite que você descompacte um ByteArray compactado de acordo com um algoritmo de compactação. Após chamar compress() e uncompress(), o comprimento da matriz de bytes é definida para o novo comprimento e a propriedade position é definida para o fim. A classe CompressionAlgorithm (AIR) define constantes que você pode usar para especificar o algoritmo de compactação. A classe ByteArray suporta os algoritmos deflate (apenas no AIR) e zlib. O algoritmo de compactação deflate é usado em vários formatos de compactação, tais como zlib, gzip e algumas implementações zip. O formato de dados compactado zlib é descrito em http://www.ietf.org/rfc/rfc1950.txt e o algoritmo de compactação deflate é descrito em http://www.ietf.org/rfc/rfc1951.txt. O exemplo a seguir compacta um ByteArray chamado bytes usando o algoritmo deflate: bytes.compress(CompressionAlgorithm.DEFLATE); O exemplo a seguir descompacta um ByteArray compactado usando o algoritmo deflate: bytes.uncompress(CompressionAlgorithm.DEFLATE); Leitura e escrita de objetosOs métodos readObject() e writeObject() lêem um objeto de e escrevem um objeto para um ByteArray, codificado em AMF serializado. AMF é um protocolo de mensagens proprietário criado pela Adobe e usado por várias classes do ActionScript 3.0, incluindo Netstream, NetConnection, NetStream, LocalConnection e Shared Objects. Um marcador de tipo de um byte descreve o tipo dos dados codificados que segue. O AMF usa os 13 tipos de dados a seguir: 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 Os dados codificados seguem o marcador de tipo, a menos que o marcador represente um único valor possível, como null ou true ou false, em cujo caso nada mais é codificado. Existem duas versões do AMF: AMF0 e AMF3. O AMF 0 suporta o envio de objetos complexos por referência e permite pontos de extremidade para restaurar as relações entre objetos. O AMF 3 melhora o AMF 0 enviando características de objetos e seqüências de caracteres por referência, além de referências de objetos, e suportando novos tipos de dados introduzidos no ActionScript 3.0. A propriedade ByteArray.objectEcoding especifica a versão do AMF usada para codificar os dados do objeto. A classe flash.net.ObjectEncoding define constantes para especificar a versão do AMF: ObjectEncoding.AMF0 e ObjectEncoding.AMF3. O exemplo a seguir chama writeObject() para escrever um objeto XML para um ByteArray, que ele, em seguida compacta usando o algoritmo Deflate e escreve para o arquivo order na área de trabalho. O exemplo usa um rótulo para exibir a mensagem “Arquivo de ordem escrito na área de trabalho!” na janela do AIR quando concluído. /* 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> */ O método readObject() lê um objeto no AMF serializado de um ByteArray e o armazena em um objeto do tipo especificado. O exemplo a seguir lê o arquivo order da área de trabalho em um ByteArray (inBytes), o descompacta e chama readObject() para armazená-lo no objeto XML orderXML. O exemplo usa uma construção de loop for each() para adicionar cada nó a uma área de texto para exibição. O exemplo também exibe o valor da propriedade objectEncoding juntamente com um cabeçalho para o conteúdo do arquivo 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> */ |
![]() |