File.load() seemingly randomly crashing the program - actionscript-3

My program has an export / import function that uses AS3Commons3-zip to make zipfiles of some content (pictures, small videos, small pdf's) inside the program. User selects an topic to make the zipfile out of, selects save location, program copies the files to tempDir (with File.createTempDirectory method) and then it loops through the tempDir with following code:
public function fileSelected(event:Event):void{
zipFile = event.currentTarget as File;
addFileToZip(tempDir, zip);
}
public function addFileToZip(file:File, zip:Zip, path:String=""):void{
if(file.isDirectory){
var directory:Array = file.getDirectoryListing();
filesToCompress = filesToCompress + directory.length;
dispatchEvent(new
for each (var f:File in directory){
addFileToZip(f, zip, path + "/" + file.name);
}
fileAddedToZip();
}else{
file.addEventListener(Event.COMPLETE, function():void{
var pathSplit:Array = file.nativePath.split(".tmp\\",2);
var fileNamePath:String = pathSplit[1] as String;
zip.addFile(fileNamePath, file.data);
fileAddedToZip();
});
file.addEventListener(ProgressEvent.PROGRESS, function(e:ProgressEvent):void{
totalLoaded = totalLoaded+e.bytesLoaded;
trace(totalLoaded+" <---TOTAL LOADED");
});
file.load();
}
}
public function fileAddedToZip():void{
filesCompressed++;
if (filesToCompress == filesCompressed){
var stream:FileStream = new FileStream();
stream.open(zipFile, FileMode.WRITE);
zip.serialize(stream);
stream.close();
tempDir.deleteDirectoryAsync(true);
}
}
And the code itself seems to work fine: the zip files import and export perfectly fine. Problem is that the program crashes at seemingly random times. Sometimes it goes through with 30 files, sometimes it crashes with 3. Sometimes it manages to make the same zip from same files 3 times in a row, then it crashes on the fourth try on some file and fifth try crashes on different file.
For example: Five tries with 35 copies of same image exported into the zip:
35/35, TOTAL LOADED trace: 3110337
35/35, TOTAL LOADED trace: 3110337
CRASH, TOTAL LOADED trace: 0 after initializing 26 files
35/35, TOTAL LOADED trace: 3110337
35/35, TOTAL LOADED trace: 3110337
CRASH, TOTAL LOADED trace: 0 after initializing 14 files
CRASH, crashed initializing first file
35/35, TOTAL LOADED trace: 3110337
35/35, TOTAL LOADED trace: 3110337
FREEZE WITH NO CRASH (stuck on file 17/35, cancel button works etc.), TOTAL LOADED trace: 1282932
I can see no pattern with it. File.load() method seems to be the culprit but no idea why. Crashes throw no errors at all. Only thing that is certain is that more the image sizes are in total (still under 100MB) the crashes are more common. Any ideas?

Solved this by using URLLoader instead:
var request:URLRequest = new URLRequest(file.nativePath);
var urlLoader:URLLoader = new URLLoader(request);
urlLoader.addEventListener(Event.COMPLETE, function (event:Event):void {
var pathSplit:Array = file.nativePath.split(".tmp\\",2);
var fileNamePath:String = pathSplit[1] as String;
zip.addFile(fileNamePath, event.target.data);
fileAddedToZip();
});
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.load(request);

Related

Animate 2021 Action Script 3 URLRequest causes Error 2035

I'm working on an application and we are using Flash to add an interface. During the initialize the app loads in a config file with references to image paths. When I use the Loader and URLRequest classes to load those images the path is not working and it's causing issues. Based on everything I've researched my code should work. I have a trace that outputs "source/icons/default.png" which is the correct relative path for the external image and loading the image works, but I need to use a variable to set the image path. Setting the URLRequest with a variable, new URLRequest("source/icons/" + default.png);, causes it use a full file path that looks wrong and reports a 2035 error. Is there something that I'm doing wrong? I'm not sure what to do at this point. I've verified the file exists and I've verified the path of the file.
Trace Ouput:
source/icons/default.png
Error Output:
[CompanionStatus] Error occurred while loading bitmap
[CompanionStatus] 2035 : Error #2035: URL Not Found. URL: file:///C|/Users/devtrooper/Desktop/project/source/icons/default.png
It looks like flash is replacing the colon (:) near the drive letter with a pipe (|) and I'm not sure if that is the issue.
Here is my method for loading images:
private function getBitmapData(nameString:String, imagePath:String):void{
try{
var bitmapDataFunction:Function = addBitmapDataToDictionary(nameString);
var path:String = ICON_FOLDER_PATH + imagePath;
var loader:Loader = new Loader();
var urlRequest:URLRequest = new URLRequest("source/icons/" + imagePath);
trace("URLRequest.url " + urlRequest.url);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, bitmapDataFunction, false, 0, true);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, handleBitmapDataError, false, 0, true);
loader.load(urlRequest);
} catch (e:Error) {
log("Error occured while trying to load image data");
log(e.name + " : " + e.message);
}
}
you can use File method instead of urlRequest method like this:
var urlPath:String="";
var picFile:File = File.desktopDirectory.resolvePath("source/icons/default.png");//you can use applicationDirectory,applicationStorageDirectory,userDirectory,doumenntDirectory and ...
if (picFile.exists == true) {
urlPath = picFile.url;
}

IO_Error opening file using Adobe Air App on a Mac

I have an Adobe Air Application that would open an csv file on Mac. I am getting an error which I am not getting with the same app for Windows, so I am thinking something about file locations, etc is amiss. Here is the code:
var file: File = File.applicationStorageDirectory;
file = file.resolvePath("A&P plans");
file.addEventListener(FileListEvent.SELECT_MULTIPLE, filesSelected);
function filesSelected(event: FileListEvent): void {
//trace(event.files.length);
fileList = new Array();
fileNames = new Array();
for (var i: uint = 0; i < event.files.length; i++) {
fileList.push(event.files[i].nativePath);
trace("name of file loaded is ", event.files[i].name, "where :", event.files[i].nativePath);
}
}
var urlRequest: URLRequest = new URLRequest(fileList[0]);
function openCSVFile():void{
csv = new CSV(urlRequest);
csv.addEventListener(Event.COMPLETE,onComplete);
csv.addEventListener(IOErrorEvent.IO_ERROR, onErrorOpening);
function onComplete(event:Event):void{
trace("file open successful");
}
function onErrorOpening(event:IOErrorEvent):void{
trace ("error opening file");
}
}
The URLRequest trace shows the location where it should be, so the app knows where to look, and it does find the file. Here is the result of the trace :/Applications/myApp.app/Contents/Resources/A&P plans/majors/NationalLeague.csv. Yet, instead of the completeEvent showing the trace, the errorEvent is inovked. Any ideas where to look for the issue? The file does not have any weird characters in its name or anything. Tracing the error shows the following: Error #2032: Stream Error. Thanks
Quite possibly the ampersand and the space in 'A&P plans' might be troublesome.
Try removing/changing those.

how understand url not reachable (IOError) ?

There are images inside of folder names like Slide1.jpg,Slide2.jpg, until Slide20.jpg. But program doesn't know how many images inside of folder. I dont want to count them also.(lets say total number of images = 100). But when press nextBtn until Slide20.jpg program will take:
Error #2044: Unhandled IOErrorEvent:. text=Error #2036: Load Never
Completed
When program Catches that error logically, it means there is no file name like Slide21.jpg. Which means total image number is 20. I want to go back when take at first time that error. Thanks for any advice
var totalImages=100;
var imageNumber=1;
var myLoader:Loader = new Loader();
//************LOADING IMAGES TO STAGE********************//
//elearningau.com/nondynamic/
var myRequest:URLRequest = new URLRequest("http://elearning.com/upandshow/Images/Slide"+imageNumber+".JPG");
myLoader.load(myRequest);
addChildAt(myLoader,1)
rightButton.addEventListener(MouseEvent.CLICK, nextImage);
function nextImage(event:MouseEvent){
if(imageNumber<totalImages)
{
imageNumber++;
} else {
imageNumber = 1;
}
reload();
}
function reload(){
removeChild(myLoader);
myRequest= new URLRequest("http://elearning.com/upandshow/Images/Slide"+imageNumber+".JPG");
myLoader.load(myRequest);
addChildAt(myLoader, 1);
}
You need to listen for errors:
myLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
function ioErrorHandler(event:IOErrorEvent):void {
// this means there was an error - do whatever you want
}

Adobe AIR : Worker can't load file

I have an issue with Workers in AIR : when I try to open a file in a non-primordial Worker, I get a Security error. When I try the same code in the primordial Worker, it works well.
I load another swf and pass its bytes when creating the second Worker.
First, I tried with URLLoader (code in 2nd worker) :
// Loading XML test
var loader:URLLoader = new URLLoader(new URLRequest('app:/config/generator/galaxy.xml'));
loader.addEventListener(Event.COMPLETE, function(evt:Event):void
{
// Trace
CEThreadDebugger.log(XML(loader.data).toString());
});
loader.addEventListener(IOErrorEvent.IO_ERROR, function(evt:IOErrorEvent):void
{
CEThreadDebugger.log(evt.text, CEThreadDebugger.ERROR);
});
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function(evt:SecurityErrorEvent):void
{
CEThreadDebugger.log(evt.text, CEThreadDebugger.ERROR);
});
I get this error :
[LOG]ERROR->Error #2048: Security sandbox violation: app:/SombresCieux.swf cannot load data from app:/config/generator/galaxy.xml.
Then I tried with File :
var file:File = File.applicationDirectory.resolvePath('config/generator/galaxy.xml');
var stream:FileStream = new FileStream();
stream.open(file, FileMode.READ);
var xml:XML = XML(stream.readUTFBytes(stream.bytesAvailable));
stream.close();
And I get this error (my code is in _mainToWorker method) :
[LOG]INFO->Error #0 : SecurityError -> file
SecurityError: file
at flash.filesystem::File$/initAppResourceDir()
at flash.filesystem::File$/get appResourceDirectoryPath()
at flash.filesystem::File$/get applicationDirectory()
at generator::Generator/_mainToWorker()
at engine.generic.system.concurrency::CEThreadMain/Evt_mainToWorker()
I noticed that the error comes from this line alone :
var file:File = File.applicationDirectory.resolvePath('config/generator/galaxy.xml');
So it works in the primordial Worker (main app), but not in the threads...
Can't the Workers access system's files nor load any file ? It's a quite huge limitation...
Thanks for the replies !
public function createWorker(swf:ByteArray,
giveAppPrivileges:Boolean = false):Worker
giveAppPrivileges:Boolean (default = false) — indicates whether the worker should be given application sandbox privileges in AIR. This parameter is ignored in Flash Player

Zip a folder in as3 Adobe AIR

I have created an Air app that after user interaction will creat a folder with bmp's, xml and text doc's.
All works apart from making the final zip which needs to be automatic.
I have been looking for a solution to this but cant find it.
Perhaps I am just not seeing it, and if so, can someone show me please.
My original posting on this is here ---
zip many files with Air as3 flash
The closest thing I have found was this one --- zip a folder using fzip
But for some reason my coment was deleted which was --
I like this. It is the closest I have come to a working solution to my own problem. That said, I tested this and it works nicely as is. Can this script be moded to run without interaction??? I am in need of it for a program that I have written. ANY asistance is welcom........ apart from just pointing me to Adobe referance as it dose not have anything like what I need. (well that I can see or find)
So now I am re-asking the comunity.
For some reason it will work with manual selection and manual save-to, but not aotonomusly.
There must be a workround to this even if it requires another full page of script.
====================================================================
UPDATE:
For closing this off, I have finally got my solution.
You can find it here. "zip file contents have no data".
Hope that my problem can help someone in the future.
Try using the as3 commons zip library.
http://www.as3commons.org/as3-commons-zip/index.html
In order to do this you're going to need to load your directory, loop through all its contents and load each asset.
This code snippet includes a bulk loader to handle that for you.
warning
I pulled most of this code out of a project where I was doing something similar but I have not tested it as is. There may be some syntax errors!
private var zip:Zip;
zip = new Zip();
zip.addEventListener(IOErrorEvent.IO_ERROR, this.createNewZip); //creates a new zip
zip.addEventListener(Event.COMPLETE, handleZipLoaded); //loads the current zip, this is not shown here
zip.load(new URLRequest(File.applicationStorageDirectory.resolvePath("myZip.zip").url)); //path to your zip file
Method to create your new zip file
private function createNewZip(e:IOErrorEvent):void{
trace("no zip");
var stream:FileStream = new FileStream();
stream.open(File.applicationStorageDirectory.resolvePath("myZip.zip"), FileMode.WRITE);
zip.serialize(stream);
stream.close();
}
You can use this to add all items in a directory to your zip file.
private function addDirToZip():void{
var f:File = File.resolvePath("Your Dir");
//this will be called when your directory listing has loaded
f.addEventListener(FileListEvent.DIRECTORY_LISTING, handleDirLoaded);
//you can also get the dir listing inline and not use a listener
//doing it async will prevent ui lock
f.getDirectoryListingAsync();
}
Next your going to need to load all of the files
protected function handleDirLoaded(e:FileListEvent):void{
loadExternal = new Vector.<File>; //vector used to keep a handle on all files
e.target.removeEventListener(FileListEvent.DIRECTORY_LISTING, handleDirLoaded);
for(var i:int = 0 ; i < files.length ; i++){
var f:File = files[i] as File;
if(f.extension == "File Types you want"){ //you can do some file type checking here
loadExternal.push(f);
}
}
//start loading in the files
loadFile();
}
This will go through the loadExternal vector and load all files
private function loadFile():void{
currentFile = loadExternal.shift(); //returns the first item off the array
//load the file
var l:Loader = new Loader();
l.contentLoaderInfo.addEventListener(Event.COMPLETE, handleLoaded);
l.load(new URLRequest(currentFile.url));
}
Once each item is loaded you can store it for addition into the zip
private function handleLoaded(e:Event):void{
var l:Loader = e.target.loader as Loader;
l.contentLoaderInfo.removeEventListener(Event.COMPLETE, handleLoaded);
//storing everything in a dictionary
assets[currentFile.name] = l.content;
//if we still have items to load go and do it all again
if(loadExternal.length != 0){
loadFile();
} else {
//now all files are loaded so lets add them to the zip
addAssetsToZip();
}
}
This is where all the loaded files actually get put into the zip and it is saved
private funcion addAssetsToZip():void{
for(var fileName:String in assets){
var ba:ByteArray = new ByteArray(); //going to write this to the zip
//make an object that holds the data and filename
var data:Object = {};
data.name = fileName;
data.content = assets[fileName];
ba.writeObject(data);
//write this file to the zip
zip.addFile(key, ba, false);
}
//and finally save everything out
zip.close();
var stream:FileStream = new FileStream();
stream.open(File.applicationStorageDirectory.resolvePath("myZip.zip"), FileMode.WRITE);
zip.serialize(stream);
stream.close();
}