[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2510
  • Last Modified:

What is causing File IO errors during Flash upload?

I have a webpage that uses Flash and the FileReference class to upload files simultaneously.  It works well 90% of the time, but with certain sets of seemingly random files I get IO Errors.  None of the files are locked or in use.  They are of a wide variety in terms of their extensions and sizes.  And each of the files can be uploaded one at a time.  It's a very confusing problem.  Based on the code, are there any obvious reasons why these IO errors would happen?  Or, maybe changing the code to upload consecutively would help?

BTW, I am using Flash 8 but I tried compiling in a demo version of the most recent Flash and it still happens.
// Based off the tutorial found at http://markshu.ca/imm/flash/tutorial/fileReference.html 
// changed to use FileReferenceList for multiple file selection. 
 
 
import flash.net.FileReference; 
import flash.net.FileReferenceList; 
 
 
uploadButn.enabled = false; 
setProperty("TTip2", _visible, "0"); 
var fileRefList:FileReferenceList = new FileReferenceList(); 
 
 
var totalBytes:Number = 0; 
var uploadedBytes:Number = 0; 
var uploadedBytes2:Array; 
var ttip:Number=0; 
var filesCompleted:Number = 0; 
var totalFiles:Number = 0; 
var fileRefListener:Object = new Object(); 
 
 
_root.progressBar.visible = false; 
 
 
function reDrawPB (pb, xCor, yCor) { 
        _root.destroyObject(pb); 
        _root.createObject("ProgressBar",pb,0); 
        _root.progressBar.move(xCor,yCor); 
        _root.progressBar.label = "UPLOADING %3%% "; 
 
 
 
} 
 
 
fileRefListener.onSelect = function 
(fileRefList:FileReferenceList):Void { 
        uploadButn.enabled = true; 
        reDrawPB("progressBar", 272.0, 9.0); 
        status_txt.text = "Files selected to upload: \n"; 
        status_txt.vPosition = status_txt.maxVPosition; 
        var list:Array = fileRefList.fileList; 
    var fileRef:FileReference; 
        totalBytes = 0; 
    for(var i:Number = 0; i < list.length; i++) { 
        fileRef = list[i]; 
                totalBytes += fileRef.size; 
                status_txt.text += fileRef.name + '\n'; 
                status_txt.vPosition = status_txt.maxVPosition; 
    } 
        status_txt.text += list.length + " file(s) selected at "; 
        status_txt.text += GetSizeType(totalBytes); 
        status_txt.vPosition = status_txt.maxVPosition; 
 
 
} 
 
 
fileRefListener.onCancel = function (fileRef:FileReference):Void { 
        uploadButn.enabled = false; 
        status_txt.text ="No files selected. \n"; 
        status_txt.vPosition = status_txt.maxVPosition; 
 
 
} 
 
 
fileRefListener.onOpen = function (fileRef:FileReference):Void { 
        status_txt.text +="Uploading " + fileRef.name + " please wait...\n"; 
        status_txt.vPosition = status_txt.maxVPosition; 
        txtUsername.text=username; 
        txtOrder.text=ordernum; 
 
 
} 
 
 
fileRefListener.onProgress = function (fileRef:FileReference, 
bytesLoaded:Number, bytesTotal:Number):Void { 
        progressBar.mode = "manual"; 
        var temp:Number = bytesLoaded - uploadedBytes2[fileRef.name] 
        uploadedBytes2[fileRef.name] = bytesLoaded; 
        uploadedBytes += temp; 
        progressBar.setProgress(uploadedBytes, totalBytes); 
        txtUploaded.text = GetSizeType(uploadedBytes); 
        txtTotal.text = GetSizeType(totalBytes); 
 
 
} 
 
 
fileRefListener.onComplete = function (fileRef:FileReference):Void { 
        status_txt.text += fileRef.name + " uploaded.\n"; 
        status_txt.vPosition = status_txt.maxVPosition; 
        filesCompleted++; 
        status_txt.text +=  filesCompleted + " of " + totalFiles + " files 
completed.\n"; 
        status_txt.vPosition = status_txt.maxVPosition; 
        if(filesCompleted == totalFiles) 
                FinishedUpload(); 
 
 
} 
 
 
fileRefListener.onHTTPError = function(fileRef:FileReference):Void { 
        status_txt.text += "There was an error uploading " + fileRef.name + 
"\n"; 
        status_txt.vPosition = status_txt.maxVPosition; 
 
 
} 
 
 
fileRefListener.onIOError = function(fileRef:FileReference):Void { 
        status_txt.text += "There was an IO error uploading " + fileRef.name 
+ "\n"; 
        status_txt.vPosition = status_txt.maxVPosition; 
 
 
} 
 
 
fileRefListener.onSecurityError = function(fileRef:FileReference, 
errorString:String):Void { 
        status_txt.text += "There was a security error accessing " + 
fileRef.name + " errorString: " + errorString +  "\n"; 
        status_txt.vPosition = status_txt.maxVPosition; 
 
 
} 
 
 
fileRefList.addListener(fileRefListener); 
 
browseButn.clickHandler = function () { 
        fileRefList.browse(); 
 
 
 
} 
 
 
browseButn.onRollOver = function() 
{ 
 
                setProperty("TTip2", _visible, "1"); 
 
 
 
} 
 
 
browseButn.onRollOut = function(){ 
setProperty("TTip2", _visible, "0"); 
 
 
} 
 
 
uploadButn.clickHandler = function () { 
        var list:Array = fileRefList.fileList; 
        var fileRef:FileReference; 
        if(uploadButn.label == "UPLOAD") 
        { 
                browseButn.enabled = false; 
                uploadButn.label = "CANCEL"; 
                status_txt.text = "Starting Upload:" + '\n'; 
                status_txt.vPosition = status_txt.maxVPosition; 
                totalFiles = list.length; 
                filesCompleted = 0; 
                uploadedBytes = 0; 
                uploadedBytes2 = []; 
                txtOf.text = "of"; 
                for(var i:Number = 0; i < list.length; i++) { 
                        fileRef = list[i]; 
                        status_txt.text +="Attempting to upload " + fileRef.name + '\n'; 
                        status_txt.vPosition = status_txt.maxVPosition; 
                        fileRef.addListener(fileRefListener) 
                        uploadedBytes2[fileRef.name] = 0; 
                        if(uploadPage != undefined) 
                                fileRef.upload(uploadPage); 
                } 
        } 
        else 
        { 
                status_txt.text += "Upload Canceled." + '\n'; 
                status_txt.vPosition = status_txt.maxVPosition; 
                for(var i:Number = 0; i < list.length; i++) { 
                        fileRef = list[i]; 
                        fileRef.cancel(); 
                } 
                uploadButn.label = "UPLOAD"; 
                browseButn.enabled = true; 
        } 
 
 
} 
 
 
function FinishedUpload() 
{ 
        uploadButn.enabled = false; 
        uploadButn.label = "UPLOAD"; 
        browseButn.enabled = true; 
        if(completeFunction != undefined) 
        { 
                getURL('javascript:' + completeFunction); 
        } 
 
 
} 
 
 
function GetSizeType(size:Number) 
{ 
        if(size < 1024) 
                return int(size*100)/100 + " bytes"; 
        if(size < 1048576) 
                return int((size / 1024)*100)/100 + "KB"; 
        if(size < 1073741824) 
           return int((size / 1048576)*100)/100 + "MB"; 
         return int((size / 1073741824)*100)/100 + "GB";

Open in new window

0
dparkes
Asked:
dparkes
  • 3
  • 2
1 Solution
 
dparkesAuthor Commented:
I have rewritten the code to upload files consecutively and the problem is gone.  Apparently there is some kind of bug during the simultaneous upload process.  Anyway, problem solved,
0
 
GrlyCommented:
I am interested in reviewing your rewritten code.  Are you able to post it here to share with everyone?
0
 
dparkesAuthor Commented:
It's been awhile, but I have the updated code with the comment "//Added by **" at the end of every line that was added (or changed).  

Most of the changes (like hiding and showing buttons) may have been for purposes other than making the upload consecutive.  

The main change was, within the uploadButn.clickHandler, taking out the loop adding the files to an array, and putting them in one at a time instead:
/*
for(var i:Number = 0; i < list.length; i++) {
AddUploadFile(i);
}
*/
AddUploadFile(filesCompleted);    



And handling the fileCompleted integer in the OnCompleted function:

      if(filesCompleted < totalFiles) AddUploadFile(filesCompleted);      
      if(filesCompleted == totalFiles)
            FinishedUpload();


Anyway, The complete code is below.

It's worked ever since with no problems whatsoever except perhaps server timeouts after an hour or more.  I'm not sure why files need to be uploaded simultaneously anyway.  

// Based off the tutorial found at http://markshu.ca/imm/flash/tutorial/fileReference.html
// changed to use FileReferenceList for multiple file selection.
 
//import the FileReference Object
import flash.net.FileReference;
import flash.net.FileReferenceList;
 
//initial settings - since no upload file type selet yet user cannot upload a file
uploadButn.enabled = false;
setProperty("TTip2", _visible, "0");
setProperty("error", _visible, "0"); // Added by **
//create a new FileReference object
var fileRefList:FileReferenceList = new FileReferenceList();
 
// variables to keep track of how many bytes have been uploaded so far and you many more to go
var totalBytes:Number = 0;
var uploadedBytes:Number = 0;
var uploadedBytes2:Array;
var ttip:Number=0;
// variables to keep track of completed files
var filesCompleted:Number = 0;
var totalFiles:Number = 0;
//create a listener object for FileReference events
var fileRefListener:Object = new Object();
 
//Use to limit the type of files in the browse dialog box
//fileDescription = "Images and Zips";
//fileExtension = "*.jpg; *.jpeg; *.gif; *.png; *.zip";
 
_root.progressBar.visible = false;
_root.error.visible = false; // Added by **
 
//a small function to redraw (reset) the progress bar
function reDrawPB (pb, xCor, yCor) {
	_root.destroyObject(pb);
	_root.createObject("ProgressBar",pb,0);
   	_root.progressBar.move(xCor,yCor);
	_root.progressBar.label = "UPLOADING %3%% ";
}
 
//===================== FILEREFERENCE EVENT HANDLER =====================//
 
//When user selects a file from the file-browsing dialog box, 
//the onSelect() method is called, and passed a reference to the FileReference object
 
fileRefListener.onSelect = function (fileRefList:FileReferenceList):Void {
	// allow user to upload
		setProperty("error", _visible, "0");  // Added by **
	uploadButn.enabled = true;
	reDrawPB("progressBar", 272.0, 25.0);
	status_txt.text = "Files selected to upload: \n";
	status_txt.vPosition = status_txt.maxVPosition;
	var list:Array = fileRefList.fileList;
    var fileRef:FileReference;
	// set totalbytes to 0 and then add the file sizes up
	totalBytes = 0;
	// loop through FileReferenceList and print out all the files selected
    for(var i:Number = 0; i < list.length; i++) {
        fileRef = list[i];
		totalBytes += fileRef.size;
		status_txt.text += fileRef.name + '\n';
		status_txt.vPosition = status_txt.maxVPosition;
    }
	// show the total file size
	status_txt.text += list.length + " file(s) selected at ";
	status_txt.text += GetSizeType(totalBytes);
	status_txt.vPosition = status_txt.maxVPosition;
}
 
//When user dismiss the file-browsing dialog box, 
//the onCancel() method is called, and passed a reference to the FileReference object
fileRefListener.onCancel = function (fileRef:FileReference):Void {
	uploadButn.enabled = false;
	status_txt.text ="No files selected. \n";
	status_txt.vPosition = status_txt.maxVPosition;	
}
 
//When the file upload/download process started, 
//the onOpen() method is called, and passed a reference to the FileReference object
fileRefListener.onOpen = function (fileRef:FileReference):Void {	
	status_txt.text +="Uploading " + fileRef.name + " please wait...\n";	
	status_txt.vPosition = status_txt.maxVPosition;
}
 
//The onProgress() method is called periodically during the file upload operation
 
fileRefListener.onProgress = function (fileRef:FileReference, bytesLoaded:Number, bytesTotal:Number):Void {
	//setting the status bar function
	progressBar.mode = "manual";
	// Allows us to keep track of the total amount uploaded and set the progress bar
	var temp:Number = bytesLoaded - uploadedBytes2[fileRef.name]
	uploadedBytes2[fileRef.name] = bytesLoaded;
	uploadedBytes += temp;
	progressBar.setProgress(uploadedBytes, totalBytes);
	txtUploaded.text = GetSizeType(uploadedBytes);
	txtTotal.text = GetSizeType(totalBytes);
 
}
 
 
//When the file upload/download operation is successfully complete, 
//the onComplete() method is called, and passed a reference to the FileReference object
fileRefListener.onComplete = function (fileRef:FileReference):Void {
	status_txt.text += fileRef.name + " uploaded.\n";
	status_txt.vPosition = status_txt.maxVPosition;
	//upload is now complete, increment fileCompleted and write out to display
	filesCompleted++;
	status_txt.text +=  filesCompleted + " of " + totalFiles + " files completed.\n";
	status_txt.vPosition = status_txt.maxVPosition;
	// Once all files are uploaded, call the FinishUpload function to finish things up
	
	if(filesCompleted < totalFiles) AddUploadFile(filesCompleted);  // Added by **
	
	if(filesCompleted == totalFiles)
		FinishedUpload();
}
 
 
fileRefListener.onHTTPError = function(fileRef:FileReference):Void {
	// show error to user
	status_txt.text += "There was an error uploading " + fileRef.name + "\n";
	status_txt.vPosition = status_txt.maxVPosition;
}
 
fileRefListener.onIOError = function(fileRef:FileReference):Void {
    //trace("onIOError: " + file.name);
	// show error to user
	status_txt.text += "There was an IO error uploading " + fileRef.name + "\n";
	status_txt.vPosition = status_txt.maxVPosition;
	
	status_txt.text +=  "Remaining uploads cancelled.\n";// added by **
	status_txt.vPosition = status_txt.maxVPosition;// added by **
	filesCompleted == totalFiles; // added by **
	status_txt.vPosition = status_txt.maxVPosition; // added by **
	for(var i:Number = 0; i < list.length; i++) { // added by **
		fileRef = list[i]; // added by **
		fileRef.cancel(); // added by **
	}
	uploadButn.label = "UPLOAD"; // added by **
	browseButn.enabled = true; // added by **
	error.move(260, 10);
	setProperty("error", _visible, "1");  // Added by **
	setProperty("browseButn", _visible, "0");  // Added by **
	setProperty("txtUploaded", _visible, "0");  // Added by **  
	setProperty("txtOf", _visible, "0");  // Added by ** 
	setProperty("txtTotal", _visible, "0");  // Added by **
	setProperty("progressBar", _visible, "0");  // Added by **
		
	//FinishedUpload(); // added by **
}
 
fileRefListener.onSecurityError = function(fileRef:FileReference, errorString:String):Void {
    //trace("onSecurityError: " + file.name + " errorString: " + errorString);
	// show error to user
	status_txt.text += "There was a security error accessing " + fileRef.name + " errorString: " + errorString +  "\n";
	status_txt.vPosition = status_txt.maxVPosition;
}
 
 
 
//****************************************************************************************//
 
//attach Listener to the FileReference Object
fileRefList.addListener(fileRefListener);
 
//button event for the browse button
browseButn.clickHandler = function () {
	//The browse function is the key, coz it displays a file-browsing dialog box
	//in which the user can select a local file to upload
	// if you want to limit the types of files the user can select to upload use the following
	// these are set earlier in the code
	//fileRefList.browse([{description: fileDescription, extension: fileExtension}]);
	// otherwise, just call the browse function.
	fileRefList.browse();
}
 
browseButn.onRollOver = function()
{ 
 
		setProperty("TTip2", _visible, "1"); 
 
}
 
browseButn.onRollOut = function(){ 
setProperty("TTip2", _visible, "0"); 
}
 
 
//Button event for the upload button
uploadButn.clickHandler = function () {
	var list:Array = fileRefList.fileList;
	var fileRef:FileReference;
	// the upload button also acts as the cancel upload button.
	if(uploadButn.label == "UPLOAD")
	{			
		browseButn.enabled = false;
		uploadButn.label = "CANCEL";
		setProperty("uploadButn", _visible, "0");   // Added by **
		setProperty("browseButn", _visible, "0");  // Added by **
		status_txt.text = "Starting Upload:" + '\n';
		status_txt.vPosition = status_txt.maxVPosition;		
		totalFiles = list.length;
		// these help keep track of how much has been uploaded, used in the onProgress even.
		filesCompleted = 0;
		uploadedBytes = 0;
		uploadedBytes2 = [];
		// I'm not the best at action script. I tried to set visible to false on the txtOf
		// and then show it when ready, but it wasn't working, so I'm just setting the text instead.
		txtOf.text = "of";
		// loop through the list of FileReferences and add the event handler to them, and then 
		// call the upload function
		
		
		/* // Remmed out by **
		for(var i:Number = 0; i < list.length; i++) {
			AddUploadFile(i);
		}
		*/
		
		AddUploadFile(filesCompleted);       // Added by **
		
	}
	else
	{		
		status_txt.text += "Upload Canceled." + '\n';
		status_txt.vPosition = status_txt.maxVPosition;
		for(var i:Number = 0; i < list.length; i++) {
			fileRef = list[i];
			fileRef.cancel();
		}
		uploadButn.label = "UPLOAD";
		setProperty("uploadButn", _visible, "1");  // Added by **
		setProperty("browseButn", _visible, "1");  // Added by **
		browseButn.enabled = true;
	}
}
 
function AddUploadFile(i:Number)
{
	var list:Array = fileRefList.fileList;
	fileRef = list[i];
	//status_txt.text +="Attempting to upload " + fileRef.name + '\n';
	//status_txt.vPosition = status_txt.maxVPosition;
	fileRef.addListener(fileRefListener)
	// This keeps track of the upload to show how much has been uploaded for each file,
	// it is used in the onProgress event.
	uploadedBytes2[fileRef.name] = 0;
	//upload the file to the httphandler on the server
	// uploadPage is set in the asp.net page, it is a LoadVars variable.
	// if it isn't set, it won't upload.  This allows you to vary the page you upload to,
	// as well as pass in any query string arguments needed for the upload.
	// you can also tack on a custom file name here if you wanted.
	// depending on the uploadPage value just do something like uploadPage + "?Filename=" + customFilename
	// then you handle the file name on the server side.
	if(uploadPage != undefined)
		fileRef.upload(uploadPage);
}
 
 
// finish the upload
function FinishedUpload()
{
	uploadButn.enabled = false;
	uploadButn.label = "UPLOAD";
	browseButn.enabled = true;
	// this allows you to pass in a javascript function to call after the download
	// Say you have a gridView displaying the files you've uploaded, you can use this
	// to refresh the gridView by doing a postback.  Only called if it is set. Also a
	// LoadVars variable.
	if(completeFunction != undefined)
	{
		getURL('javascript:' + completeFunction);
	}
	
	
}
 
// Converts bytes into more redable values. Called from onProgress.
function GetSizeType(size:Number)
{
	if(size < 1024)
		return int(size*100)/100 + " bytes";
	if(size < 1048576)
		return int((size / 1024)*100)/100 + "KB";
	if(size < 1073741824)
	   return int((size / 1048576)*100)/100 + "MB";
	 return int((size / 1073741824)*100)/100 + "GB";
}

Open in new window

0
 
GrlyCommented:
Thanks for the quick reply!
0
 
dparkesAuthor Commented:
You're welcome.
0

Featured Post

Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now