views:

2079

answers:

2

Hi,

I've encountered a memory problem using FileReference.save(). My Flash application generates of a lot of data in real-time and needs to save this data to a local file. As I understand, Flash 10 (as opposed to AIR) does not support streaming to a file. But, what's even worse is that FileReference.save() duplicates all the data before saving it. I was looking for a workaround to this doubled memory usage and thought about the following approach:

What if I pass a custom subclass of ByteArray as an argument to FileReference.save(), where this ByteArray subclass would override all read*() methods. The overridden read*() methods would wait for a piece of data to be generated by my application, return this piece of data and immediately remove it from the memory. I know how much data will be generated, so I could also override length/bytesAvailable methods.

Would it be possible? Could you give me some hint how to do it? I've created a subclass of ByteArray, registered an alias for it, passed an instance of this subclass to FileReference.save(), but somehow FileReference.save() seems to treat it just as it was a ByteArray instance and doesn't call any of my overridden methods...

Thanks a lot for any help!

A: 

It's not something I've tried before, but can you try sending the data out to a php application that would handle saving the ByteArray to the server, much like saving an image to the server, so then you'd use URLLoader.data instead, using something like this:

http://www.zedia.net/2008/sending-bytearray-and-variables-to-server-side-script-at-the-same-time/

quoo
Unfortunately, this doesn't solve my problem. If I use URLLoader to download the data, I need to pass URLLoader.data to FileReference.save(), which again will duplicate URLLoader.data. So, this will result in the data being stored twice in the memory, which I need to avoid...
bartekb
Oh I'm sorry, for some reason I thought you were trying to save to the server. I'd maybe log a bug in JIRA about the data being stored twice? Otherwise... I think FileReference.save is your only way of writing to the local disk.
quoo
A: 

It's an interesting idea. Perhaps to start you should just add traces in your extended ByteArray to see how the FileReference#save() functions internally.

If it has some kind of

while( originalByteArray.bytesAvailable ) 
  writeToSaveBuffer( originalByteArray.readByte() );

functionality the overrides could just truncate the original buffer on every read like you say, something like:

override function readByte() : uint {
  var b : uint = super.readByte();
  // Truncate the bytes (assuming bytesAvailable = length - removedBytes)
  length = length - bytesAvailable;
  return b;
}

On the other hand, if this now works I guess the original byte array would not be available afterwards in the application anymore.

(i havn't tested this myself, truncating might require more work than the example)

Robert Sköld
Thanks a lot for interest! I've tried this, but none of my methods in the extended ByteArray is ever called... I suspect that FileReference#save() clones the ByteArray given as an argument using ByteArray#readObject/writeObject and then works on the cloned object. But for some weird reason, my extended ByteArray becomes just a normal ByteArray after such cloning! I've just posted this issue (which prevents me from tracing FileReference#save) as a separate problem: http://stackoverflow.com/questions/875163/trouble-cloning-an-extended-bytearray
bartekb