How to write an image to application directory using AIR?
I'm trying to save an image to the application directory by opening a file stream and write the bytes from a bitmap data. I added some events listeners for testing the file stream process but I don't receive any response event. Can you take a look over my code and tell me where might be the problem.
var bd:BitmapData = new BitmapData(CANVAS_WIDTH, CANVAS_HEIGHT);
bd.draw(currentDrawing);
var jpgEncoder:JPGEncoder = new JPGEncoder(100);
var ba:ByteArray = jpgEncoder.encode(bd);
var newImage:File = File.applicationDirectory.resolvePath("images/test.jpg");
var fileStream:FileStream = new FileStream();
fileStream.open(newImage, FileMode.UPDATE);
fileStream.writeBytes(ba);
fileStream.addEventListener(Event.CLOSE, fileClosed);
fileStream.addEventListener(Event.COMPLETE, fileComplete);
fileStream.addEventListener(IOErrorEvent.IO_ERROR, fileErr开发者_运维问答or);
fileStream.close();
function fileClosed(event:Event):void {
outputText.text = "close";
}
function fileComplete(event:Event):void {
outputText.text = "complete";
}
function fileError(event:IOErrorEvent):void {
outputText.text = "error";
}
AIR security forbids writing into app directory.
If you absolutely need to write some file into app dir, you can use native helper to do that (cmd.exe on Windows, for example.) But consider using File.applicationStorageDirectory instead - it is writable, but hidden somewhere in user profile.
flash.fileSystem.File.applicationDirectory is read-only. this is where assets you've bundled with your AIR application will appear.
for read-write access specific to your application, use flash.fileSystem.File.applicationStorageDirectory instead. you also have access to other OS specific read-write directories via File's static properties.
this SO thread lists the specific locations of the applicationStorageDirectory for Windows, Mac and Linux: The Difference Of Location Storage File in air
there is a way to write to the applicationDirectory here's the hack.
var bmo:BitmapData = new BitmapData(150, 150, false, 0xFF0000);
var bm:Bitmap = new Bitmap(bmo);
addChild(bm);
var e:JPGEncoder = new JPGEncoder(100);
var ba:ByteArray = e.encode(bmo);
var f:File = new File(File.applicationDirectory.nativePath);
f= f.resolvePath("test.jpg");
var s:FileStream = new FileStream();
s.open(f, FileMode.UPDATE);
s.writeBytes(ba);
s.close();
Because you are using the regular open()
method, you are opening the file in synchronous mode, which means that the next line (or statement rather) in your code will not be executed until the previous finishes. This means that your event listeners aren't even added until after writeBytes() finishes.
Try to simply reorder your lines of code like so:
var fileStream:FileStream = new FileStream();
fileStream.addEventListener(Event.CLOSE, fileClosed);
fileStream.addEventListener(Event.COMPLETE, fileComplete);
fileStream.addEventListener(IOErrorEvent.IO_ERROR, fileError);
fileStream.open(newImage, FileMode.UPDATE);
fileStream.writeBytes(ba);
fileStream.close();
This will make sure that the event listeners have been added before the writeBytes() method is executed (and finishes) so your event handlers will be invoked.
However, consider whether you actually need event listeners at all. Event listeners (and the "Observer" pattern which they are built upon) are generally a solution to having to wait for an asynchronous operation to finish. Since you are just using synchronous writing you probably don't even need them.
精彩评论