如何逐步写入一个巨大的bytearray文件并避免可怕的内存错误

时间:2016-02-09 18:16:10

标签: actionscript-3 air bytearray file-writing

我正在开发Air项目,下载大量(zip)文件,然后解压缩它们,最后删除它下载的原始.zip文件。

除非我想将解压缩的文件写入磁盘,否则一切都会顺利运行。

麻烦的是,我一直在遇到这个错误的小怪物的问题。

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

这是代码中给我带来悲伤的部分。当文件很小(在3 MB文件上测试)时,这非常有效,但是一旦我尝试了一个大文件(458 MB),我就会收到错误。

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 个答案:

答案 0 :(得分:0)

这很难,但我明白了。诀窍是使用&#34;序列化&#34; 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");
        }
    }