views:

238

answers:

2

I am trying to read a very large file in AS3 and am having problems with the runtime just crashing on me. I'm currently using a FileStream to open the file asynchronously. This does not work(crashes without an Exception) for files bigger than about 300MB.

_fileStream = new FileStream();
_fileStream.addEventListener(IOErrorEvent.IO_ERROR, loadError);
_fileStream.addEventListener(Event.COMPLETE, loadComplete);
_fileStream.openAsync(myFile, FileMode.READ);

In looking at the documentation, it sounds like the FileStream class still tries to read in the entire file to memory(which is bad for large files).

Is there a more suitable class to use for reading large files? I really would like something like a buffered FileStream class that only loads the bytes from the files that are going to be read next.

I'm expecting that I may need to write a class that does this for me, but then I would need to read only a piece of a file at a time. I'm assuming that I can do this by setting the position and readAhead properties of the FileStream to read a chunk out of a file at a time. I would love to save some time if there is a class like this that already exists.

Is there a good way to process large files in AS3, without loading entire contents into memory?

+1  A: 

Can't you create a stream, and read a chunk of bytes at a given offset, a chunk at a time... so:

function readPortionOfFile(starting:int, size:int):ByteArray
{
    var bytes:ByteArray ...
    var fileStream:FileStream ...    

    fileStream.open(myFile);
    fileStream.readBytes(bytes, starting, size);
    fileStream.close();

    return bytes;
}

and then repeat as required. I don't know how this works, and haven't tested it, but I was under the impression that this works.

alecmce
This is similar to what I was thinking of doing in my own implementation. I will probably just implement the extra layer of abstraction.
Kekoa
A: 

You can use the fileStream.readAhead and fileStream.position properties to set how much of the file data you want read, and where in the file you want it to be read from.

Lets say you only want to read megabyte 152 of a gigabyte file. Do this; (A gigabyte file consists of 1073741824 bytes) (Megabyte 152 starts at 158334976 bytes)

var _fileStream = new FileStream();
_fileStream.addEventListener(Event.COMPLETE,loadComplete);
_fileStream.addEventListener(ProgressEvent.PROGRESS,onBytesRead);
_fileStream.readAead = (1024 * 1024); // Read only 1 megabyte
_fileStream.openAsync(myFile,FileMode.READ);
_fileStream.position = 158334976; // Read at this position in file

var megabyte152:ByteArray = new ByteArray();

function onBytesRead(e:ProgressEvent){
e.currentTarget.readBytes(megabyte152);
if(megabyte152.length == (1024 * 1024)){
chunkReady();
}
}
function chunkReady(){
// 1 megabyte has been read successfully \
// No more data from the hard drive file will be read unless _fileStream.position changes \
}

Cristian