2016-02-09 4 views
0

Я работаю над проектом Air, который загружает огромные (zip-файлы) файлы, а затем распаковывает их и, наконец, удаляет исходный .zip-файл, который он загрузил.Как написать огромный файл bytearray в файл постепенно и избежать этой ошибки памяти

Все работает гладко, за исключением случаев, когда я хочу записать распакованный файл на диск.

Проблема в том, что я все время сталкиваюсь с проблемой этого маленького монстра ошибки.

Error: Error #1000: The system is out of memory. 

Вот часть кода, которая дает мне печаль. Это отлично работает, когда файл небольшой (протестирован на 3 Мбайт файла), но как только я попробую один из моих больших файлов (458 МБ), я получаю сообщение об ошибке.

private function unzipFile() 
    { 
     var pulledFile:FZipFile; 
     var index:int = 0; 
     var chunkSize:int = 1000000; 

     Console.log("Unzipping file..."); 
     var zip:FZip = new FZip(); 
     zip.addEventListener(Event.COMPLETE, onUnzipComplete); 
     var fileStream:FileStream = new FileStream(); 

     zip.load(new URLRequest(urlToUnzip)); 

     function onUnzipComplete(e:Event) 
     { 
      pulledFile = zip.getFileAt(0); 
      var file:File = File.documentsDirectory.resolvePath(pulledFile.filename); 
      fileStream.openAsync(file, FileMode.WRITE); 
      writeChunk(); 
     } 

     function writeChunk() 
     { 
      var bytesToGet:int = pulledFile.content.bytesAvailable; 
      if (bytesToGet > chunkSize) 
       bytesToGet = chunkSize; 

      Console.log("Writing chunk " + (int((pulledFile.content.length - pulledFile.content.bytesAvailable)/chunkSize) + 1) + " of " + (int(pulledFile.content.length/chunkSize) + 1)); 

      var fileData:ByteArray = new ByteArray(); 
      pulledFile.content.readBytes(fileData, 0, bytesToGet); 

      fileStream.writeBytes(fileData, 0, fileData.length); 

      if (index < pulledFile.content.bytesAvailable) 
      { 
       writeChunk(); 
       index += bytesToGet; 
      } 
      else 
      { 
       fileStream.close(); 
       Console.log("Unzipping complete"); 
      } 
     } 
    } 

код падает именно на линии

var bytesToGet:int = pulledFile.content.bytesAvailable; 

Как я до сих пор постепенно писать содержимое в файл, не зная, сколько байт доступны для меня? Если у меня нет доступа к свойству bytesAvailable, откуда я знаю, что я написал?

Я использую the FZip library для декомпрессии.

+1

Вместо того чтобы хранить оставшиеся ByteArray размер в локальной переменной, попытайтесь проверить, если '(pulledFile.content.bytesAvailable> 0)', а затем взять кусок или меньшую часть из массива. – DodgerThud

+0

Я не могу получить доступ к файлам bytesAvailable вообще. Просто попробовал то, что вы предложили, не может проследить его, не может поставить его в условное утверждение, ничего. –

ответ

0

Это было сложно, но я понял это. Хитрость заключается в использовании метода «сериализации» FZip и вообще не касаться свойств содержимого ByteArray.

Вот последний код, который работает.

private function unzipFile() 
    { 
     var pulledFile:FZipFile; 

     Console.log("Decompressing file..."); 
     var zip:FZip = new FZip(); 
     zip.addEventListener(Event.COMPLETE, onUnzipComplete); 

     var fileStream:FileStream = new FileStream(); 

     zip.load(new URLRequest(urlToUnzip)); 

     function onUnzipComplete(e:Event) 
     { 
      pulledFile = zip.getFileAt(0); 
      var file:File = File.documentsDirectory.resolvePath("Easywatch/" + pulledFile.filename); 
      fileStream.open(file, FileMode.WRITE); 
      zip.serialize(fileStream, false); 
      fileStream.close(); 

      Console.log("Decompression complete"); 
     } 
    } 
+0

У меня есть почтовый файл размером 160 МБ, а файл внутри него - 516 МБ. Я пробовал этот подход выше, но он пишет только 313 МБ данных (файл поврежден), без каких-либо ошибок. Я что-то упускаю ? – Deepak

 Смежные вопросы

  • Нет связанных вопросов^_^