AS3 / AIR: ошибка IOStream при попытке загрузить файлы

Я создаю приложение AIR, в котором пользователь перетаскивает файлы изображений на сцену, приложение затем загружает эти перетаскиваемые изображения на сайт imgur.com, а затем возвращает ссылки на изображения (в формате XML).

У меня две проблемы:

  1. программа успешно работает с очень маленьким файлом, но с файлами большего размера (1 МБ или больше) я получаю ошибку IOStream 2023. Imgur поддерживает загрузку до 10 МБ, поэтому я знаю, что это должно быть что-то на моей стороне.

  2. Я хотел бы иметь возможность загружать в программу сразу несколько файлов изображений и загружать их все (синхронно или асинхронно, это не имеет значения). Прямо сейчас программа выдает ошибки, когда я пытаюсь это сделать (что-то в строке byteArray должно быть больше 0).

Ниже приведен рассматриваемый код, который вызывает у меня проблемы. (спасибо за вашу помощь в продвижении)

private function doDragDrop(e:NativeDragEvent):void
{           
    trace("doDragDrop() called.");
    var dropFiles:Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
    for each (var file:File in dropFiles)
    {
        switch (file.extension.toLowerCase())
        {
            case "jpg" :
            case "jpeg" :
            case "gif" :
            case "png" :
            case "apng" :
            case "tiff" :
            case "bmp" :
            case "pdf" :
            case "xcf" :
            trace("file Extension Check = passed");
            addImage(file.nativePath);
                break;

            //error handling for non-supported filetypes
            default :
                trace("ERROR: Unsupported File Type Detected!");
        }
    }
}

private function addImage(nativePath:String):void
{
    trace("addImage() called.");
    trace("NativePath is: " + nativePath);
    //var file:File = new File(nativePath);
    var file:File = File.desktopDirectory.resolvePath(nativePath);
    var ba:ByteArray = new ByteArray();
    var stream:FileStream = new FileStream();
    stream.open(file, FileMode.READ);
    stream.readBytes(ba);
    stream.close();         
    var loader:Loader = new Loader();
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, fileLoaded);
    loader.loadBytes(ba);
}

private function fileLoaded(e:Event):void
{
    trace("fileLoaded() called.");
    var bitmap:Bitmap = Bitmap(e.target.content);
    var bitmapData:BitmapData = bitmap.bitmapData;
    var png:ByteArray = PNGEncoder.encode(bitmapData);

    urlLoader = new URLLoader();
    urlLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
    urlLoader.addEventListener(Event.COMPLETE, onCookieSent);
    urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
    urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);

    var vars:String = "?key=" + API_KEY + "&name=name&title=title";
    var request:URLRequest = new URLRequest(UPLOAD_URL + vars);
    request.contentType = "application/octet-stream";
    request.method = URLRequestMethod.POST;
    request.data = png;
    urlLoader.load(request);
}

private function onCookieSent(e:Event):void
{
    trace("onCookieSent() called.");
    var res:XML = new XML(unescape(urlLoader.data));
    var resultsList:XMLList = res.links;
    trace(resultsList);
}

private function onIOError(e:IOErrorEvent):void 
{
    trace("ioErrorHandler: " + e);
    TweenLite.to(tv_mc, 2, {alpha:0.5, scaleX:1.0, scaleY:1.0, ease:Elastic.easeOut});
    // Handle error
}
private function onSecurityError(e:SecurityErrorEvent):void 
{
    trace("securityErrorHandler: " + e);
    TweenLite.to(tv_mc, 2, {alpha:0.5, scaleX:1.0, scaleY:1.0, ease:Elastic.easeOut});
    // handle error
}

//When the dragged object leaves the drop point, do this
private function doDragExit(e:NativeDragEvent):void
{
    trace("doDragExit() called.");
    TweenLite.to(tv_mc, 2, {alpha:0.5, scaleX:1.0, scaleY:1.0, ease:Elastic.easeOut});
}

person tdc    schedule 26.01.2012    source источник


Ответы (1)


после этого:

var ba:ByteArray = new ByteArray();
var stream:FileStream = new FileStream();
stream.open(file, FileMode.READ);
stream.readBytes(ba);
stream.close(); 

у вас уже есть ByteArray файла / изображения. не могли бы вы просто отправить это ...

private function addImage(nativePath:String):void
{
    trace("addImage() called.");
    trace("NativePath is: " + nativePath);
    //var file:File = new File(nativePath);
    var file:File = File.desktopDirectory.resolvePath(nativePath);
    var ba:ByteArray = new ByteArray();
    var stream:FileStream = new FileStream();
    stream.open(file, FileMode.READ);
    stream.readBytes(ba);
    stream.close();         

    urlLoader = new URLLoader();
    urlLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
    urlLoader.addEventListener(Event.COMPLETE, onCookieSent);
    urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
    urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);

    var vars:String = "?key=" + API_KEY + "&name=name&title=title";
    var request:URLRequest = new URLRequest(UPLOAD_URL + vars);
    request.contentType = "application/octet-stream";
    request.method = URLRequestMethod.POST;
    request.data = ba;
    urlLoader.load(request);
}
person Philipp Kyeck    schedule 26.01.2012
comment
Привет, pkyeck, похоже, ты всегда мне помогал, я ценю это :) Код, который ты предложил, прекрасно работает. Я извлек большую часть этого кода из предыдущего проекта и забыл удалить некоторые ненужные фрагменты, так что спасибо! Приложение теперь нормально загружает как маленькие, так и большие изображения. У меня есть еще 2 вещи, которые я хочу решить: 1) возможность отслеживать% загруженного прогресса (кажется, URLLoader отправляет только 0 или 100% для progressEvent?) И 2) Разрешить одновременное добавление нескольких файлов, и загрузите их все. Есть предложения по их устранению? Спасибо еще раз за помощь! - person tdc; 26.01.2012
comment
Рад, что смог помочь. (тогда не забудьте принять ответ ...). для двух оставшихся Q: 1) обычно вы должны получить больше, чем просто 0 и 100%. это так быстро, что на большее нет времени? 2) создайте очередь, чтобы при перетаскивании нескольких файлов вы загружали их один за другим. - person Philipp Kyeck; 27.01.2012
comment
Нет, я не думаю, что это так быстро, так как я использую изображение размером 6 МБ, и загрузка займет добрых 30 секунд. Я добавил событие progressEvent.PROGRESS в urlLoader, а в обработчике трассировки (e.bytesLoaded / e.bytesTotal) * 100. Он всегда отслеживает только 0% и 100%. :( 2) Есть рекомендации по созданию очереди? Должен ли я просто проверить, заканчивается ли файл правильным расширением, сохранить путь к файлу в массиве, а затем пройти через массив при загрузке / выгрузке изображения? - person tdc; 27.01.2012
comment
1) stackoverflow.com/questions/1512197/ похоже, что мониторинг прогресса при загрузке файлов не поддерживается. 2) да, добавьте каждый файл в массив и начните загружать первый. после этого удалите его из массива и снова запустите первый (бывший второй индекс в массиве) - до тех пор, пока в массиве не останется ни одного. - person Philipp Kyeck; 27.01.2012