ByteArray örneği: Bir .zip dosyasını okumaAdobe AIR 1.0 ve üstü Bu örnek, farklı türlerde birçok dosya içeren basit bir .zip dosyasının nasıl okunacağını gösterir. Bu işlemi her dosyanın meta verilerinden ilgili verileri ayıklayarak, her dosyayı bir ByteArray öğesine genişleterek ve dosyayı masaüstüne yazarak yapar. Bir .zip dosyasının genel yapısı PKWARE Inc.in belirtimine dayalıdır, bu belirtim http://www.pkware.com/documents/casestudies/APPNOTE.TXT adresinde bulunmaktadır. İlki, .zip arşivindeki ilk dosyanın dosya üstbilgisi ve dosya verileridir, ardından her ek dosyanın dosya üstbilgisi ve dosya veri çifti gelir. (Dosya üstbilgisinin yapısı daha ileride anlatılmaktadır.) İkincisi, .zip dosyası isteğe bağlı olarak bir veri tanımlayıcı kaydı içerir (genellikle çıktı zip dosyası diske kaydedilmek yerine bellekte oluşturulduğunda). Üçüncü olarak, birçok ilave isteğe bağlı öğe bulunmaktadır: arşiv şifre çözme üstbilgisi, arşiv ek veri kaydı, merkezi dizin yapısı, Zip64 merkezi dizin kaydının sonu, Zip64 merkezi dizin bulucunun sonu ve merkezi dizin kaydının sonu. Bu örnekteki kod yalnızca klasör içermeyen zip dosyalarının ayrıştırılması için yazılmıştır ve veri tanımlayıcı kayıtları beklemez. Son veri dosyasını izleyen tüm bilgileri yok sayar. Her dosya için dosya üstbilgi biçimi şöyledir:
Dosya üstbilgisinin ardından gerçek dosya verileri gelir, bu veriler sıkıştırma yöntemi bayrağına bağlı olarak sıkıştırılmış veya sıkıştırılmamış olabilir. Dosya verileri sıkıştırılmamışsa bayrak 0'dır (sıfır), DEFLATE algoritması kullanılarak sıkıştırılmışsa 8'dir veya diğer sıkıştırma algoritmaları kullanılmışsa başka bir değerdir. Bu örneğin kullanıcı arabirimi bir etiket ve metin alanından oluşur (taFiles). Uygulama aşağıdaki bilgileri .zip dosyasında karşılaştığı her dosyanın metin alanına yazar: dosya adı, sıkıştırılmış boyut ve sıkıştırılmamış boyut. Aşağıdaki MXML belgesi uygulamanın Flex versiyonuna ait kullanıcı arabirimini açıklıyor: <?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init();"> <mx:Script> <![CDATA[ // The application code goes here ]]> </mx:Script> <mx:Form> <mx:FormItem label="Output"> <mx:TextArea id="taFiles" width="320" height="150"/> </mx:FormItem> </mx:Form> </mx:WindowedApplication> Programın başlangıcı aşağıdaki görevleri gerçekleştirir:
Flex'te, program kodu init() yöntemiyle başlar ve buna kök mx:WindowedApplication için creationComplete işleyicisi etiketi adı verilir. // for Flex private function init():void { Program .zip dosyasını OKUMA modunda açarak başlar. zStream.open(zfile, FileMode.READ); Ardından, sayısal alanların bayt sıralamasında en düşük değerli baytın önce geldiğini göstermek için bytes öğesinin endian özelliğini LITTLE_ENDIAN olarak ayarlar. bytes.endian = Endian.LITTLE_ENDIAN; Sonra while() ifadesi, dosya akışındaki geçerli konum dosya boyutundan büyük veya dosya boyutuna eşit olana kadar devam eden bir döngü başlatır. while (zStream.position < zfile.size) { Döngüdeki ilk ifade dosya akışının ilk 30 baytını ByteArray bytes öğesine okur. İlk 30 bayt, ilk dosya üstbilgisinin sabit boyutlu parçasını oluşturur. // read fixed metadata portion of local file header zStream.readBytes(bytes, 0, 30); Sonra kod, 30 baytlık üstbilginin ilk baytlarından bir tam sayı (signature) okur. ZIP biçimi tanımı, her dosya üstbilgi imzasının onaltılık değer 0x04034b50 olduğunu belirtir; imza farklıysa bu, kodun, .zip dosyasının dosya kısmının ötesine taşındığı ve ayıklanacak dosya olmadığı anlamına gelir. Bu durumda kod, bayt sırasının sonunu beklemek yerine hemen while döngüsünden çıkar. bytes.position = 0; signature = bytes.readInt(); // if no longer reading data files, quit if (signature != 0x04034b50) { break; } Kodun sonraki kısmı üstbilgi baytını uzaklık konumu 8'de okur ve değeri compMethod değişkeninde saklar. Bu bayt, bu dosyayı sıkıştırmak için kullanılan sıkıştırma yöntemini gösteren bir değer içerir. Birçok sıkıştırma yöntemi kullanılabilir, ancak uygulamada neredeyse tüm .zip dosyaları DEFLATE sıkıştırma algoritmasını kullanmaktadır. Geçerli dosya DEFLATE sıkıştırmayla sıkıştırıldıysa compMethod 8'dir; dosya sıkıştırılmamışsa, compMethod 0'dır. bytes.position = 8; compMethod = bytes.readByte(); // store compression method (8 == Deflate) İlk 30 baytın ardından, üstbilginin dosya adını ve büyük olasılıkla ek bir alan içeren üstbilginin değişken uzunluklu kısmı gelir. Değişken offset bu kısmın boyutunu saklar. Boyut, uzaklık 26 ve 28'deki üstbilgilerden okunan dosya adı uzunluğu ve ek alan uzunluğu toplanarak hesaplanır. offset = 0; // stores length of variable portion of metadata bytes.position = 26; // offset to file name length flNameLength = bytes.readShort(); // store file name offset += flNameLength; // add length of file name bytes.position = 28; // offset to extra field length xfldLength = bytes.readShort(); offset += xfldLength; // add length of extra field Sonra program offset değişkeninde saklanan bayt sayısı için dosya üstbilgisinin değişken uzunluklu kısmını okur. // read variable length bytes between fixed-length header and compressed file data zStream.readBytes(bytes, 30, offset); Program, dosya adını üstbilginin değişken uzunluk kısmından okur ve dosyanın sıkıştırılmış (zip) ve sıkıştırılmamış (orijinal) boyutlarıyla birlikte metin alanında görüntüler. // Flash version bytes.position = 30; fileName = bytes.readUTFBytes(flNameLength); // read file name taFiles.appendText(fileName + "\n"); // write file name to text area bytes.position = 18; compSize = bytes.readUnsignedInt(); // store size of compressed portion taFiles.appendText("\tCompressed size is: " + compSize + '\n'); bytes.position = 22; // offset to uncompressed size uncompSize = bytes.readUnsignedInt(); // store uncompressed size taFiles.appendText("\tUncompressed size is: " + uncompSize + '\n'); // Flex version bytes.position = 30; fileName = bytes.readUTFBytes(flNameLength); // read file name taFiles.text += fileName + "\n"; // write file name to text area bytes.position = 18; compSize = bytes.readUnsignedInt(); // store size of compressed portion taFiles.text += "\tCompressed size is: " + compSize + '\n'; bytes.position = 22; // offset to uncompressed size uncompSize = bytes.readUnsignedInt(); // store uncompressed size taFiles.text += "\tUncompressed size is: " + uncompSize + '\n'; Örnek, dosyanın geri kalanını sıkıştırılmış boyut tarafından belirtilen uzunluk için dosya akışından bytes öğesine okur ve ilk 30 bayttaki dosya üstbilgisinin üzerine yazar. Dosya sıkıştırılmış olmasa bile sıkıştırılmış boyut doğrudur, çünkü bu durumda sıkıştırılmış boyut dosyanın sıkıştırılmamış boyutuna eşittir. // read compressed file to offset 0 of bytes; for uncompressed files // the compressed and uncompressed size is the same zStream.readBytes(bytes, 0, compSize); Sonra örnek, sıkıştırılmış dosyayı genişletir ve çıktı dosyası akışına yazmak için outfile() işlevini çağırır. outfile() öğesine dosya verilerini içeren dosya adını ve bayt sırasını iletir. if (compMethod == 8) // if file is compressed, uncompress { bytes.uncompress(CompressionAlgorithm.DEFLATE); } outFile(fileName, bytes); // call outFile() to write out the file Kapatma ayraçları, outFile() yöntemi haricinde, while döngüsünün, init() yönteminin ve uygulama kodunun sonunu gösterir. Çalıştırma while döngüsünün başlangıcına kadar geriye doğru ilerler ve başka bir dosyayı ayıklayarak veya son dosya işlenmişse .zip dosyasını işlemeyi sonlandırarak .zip dosyasında bulunan sonraki baytları işlemeye devam eder. } // end of while loop } // for Flex version, end of init() method and application outfile() işlevi bir çıktı dosyasını, dosyaya filename parametresi tarafından sağlanan ismi vererek masaüstünde YAZMA modunda açar. Ardından data parametresindeki dosya verilerini çıktı dosyası akışına (outStream) yazar ve dosyayı kapatır. // Flash version function outFile(fileName:String, data:ByteArray):void { var outFile:File = File.desktopDirectory; // destination 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(); } private 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(); } |
|