The read buffer and the bytesAvailable property of a FileStream object

When a FileStream object with read capabilities (one in which the fileMode parameter of the open() or openAsync() method was set to READ or UPDATE) is opened, the runtime stores the data in an internal buffer. The FileStream object begins reading data into the buffer as soon as you open the file (by calling the open() or openAsync() method of the FileStream object).

For a file opened for synchronous operations (using the open() method), you can always set the position pointer to any valid position (within the bounds of the file) and begin reading any amount of data (within the bounds of the file), as shown in the following code (which assumes that the file contains at least 100 bytes):

import openfl.display.Sprite;
import openfl.filesystem.File;
import openfl.filesystem.FileMode;
import openfl.filesystem.FileStream;
import openfl.utils.ByteArray;

class FileStreamReadBufferExample1 extends Sprite
{
    public function new()
    {
        super();

        var myByteArray = new ByteArray();

        var myFile:File = File.documentsDirectory.resolvePath("OpenFL Test/test.txt");
        var myFileStream:FileStream = new FileStream();
        myFileStream.open(myFile, FileMode.READ);
        myFileStream.position = 10;
        myFileStream.readBytes(myByteArray, 0, 20);
        myFileStream.position = 89;
        myFileStream.readBytes(myByteArray, 0, 10);
    }
}

Whether a file is opened for synchronous or asynchronous operations, the read methods always read from the "available" bytes, represented by the bytesAvalable property. When reading synchronously, all of the bytes of the file are available all of the time. When reading asynchronously, the bytes become available starting at the position specified by the position property, in a series of asynchronous buffer fills signaled by progress events.

For files opened for synchronous operations, the bytesAvailable property is always set to represent the number of bytes from the position property to the end of the file (all bytes in the file are always available for reading).

For files opened for asynchronous operations, you need to ensure that the read buffer has consumed enough data before calling a read method. For a file opened asynchronously, as the read operation progresses, the data from the file, starting at the position specified when the read operation started, is added to the buffer, and the bytesAvailable property increments with each byte read. The bytesAvailable property indicates the number of bytes available starting with the byte at the position specified by the position property to the end of the buffer. Periodically, the FileStream object sends a progress event.

For a file opened asynchronously, as data becomes available in the read buffer, the FileStream object periodically dispatches the progress event. For example, the following code reads data into a ByteArray object, bytes, as it is read into the buffer:

import openfl.display.Sprite;
import openfl.events.ProgressEvent;
import openfl.filesystem.File;
import openfl.filesystem.FileMode;
import openfl.filesystem.FileStream;
import openfl.utils.ByteArray;

class FileStreamReadBufferExample2 extends Sprite
{
    private var bytes:ByteArray;
    private var myFileStream:FileStream;

    public function new()
    {
        super();

        bytes = new ByteArray();
        var myFile:File = File.documentsDirectory.resolvePath("OpenFL Test/test.txt");
        myFileStream = new FileStream();
        myFileStream.addEventListener(ProgressEvent.PROGRESS, progressHandler);
        myFileStream.openAsync(myFile, FileMode.READ);
    }

    private function progressHandler(event:ProgressEvent):Void
    {
        myFileStream.readBytes(bytes, myFileStream.position, myFileStream.bytesAvailable);
    }
}

For a file opened asynchronously, only the data in the read buffer can be read. Furthermore, as you read the data, it is removed from the read buffer. For read operations, you need to ensure that the data exists in the read buffer before calling the read operation. For example, the following code reads 8000 bytes of data starting from position 4000 in the file:

import openfl.display.Sprite;
import openfl.events.ProgressEvent;
import openfl.filesystem.File;
import openfl.filesystem.FileMode;
import openfl.filesystem.FileStream;
import openfl.utils.ByteArray;

class FileStreamReadBufferExample3 extends Sprite
{
    private var bytes:ByteArray;
    private var myFileStream:FileStream;

    public function new()
    {
        super();

        bytes = new ByteArray();
        var myFile:File = File.documentsDirectory.resolvePath("OpenFL Test/test.txt");
        myFileStream = new FileStream();
        myFileStream.addEventListener(ProgressEvent.PROGRESS, progressHandler);
        myFileStream.openAsync(myFile, FileMode.READ);
        myFileStream.position = 4000;
    }

    private function progressHandler(event:ProgressEvent):Void
    {
        if (myFileStream.bytesAvailable > 8000 )
        {
            myFileStream.readBytes(bytes, myFileStream.position, 8000);
        }
    }
}

During a write operation, the FileStream object does not read data into the read buffer. When a write operation completes (all data in the write buffer is written to the file), the FileStream object starts a new read buffer (assuming that the associated FileStream object was opened with read capabilities), and starts reading data into the read buffer, starting from the position specified by the position property. The position property may be the position of the last byte written, or it may be a different position, if the user specifies a different value for the position object after the write operation.

results matching ""

    No results matching ""