Flash, доступ к totalBytes перед фактической загрузкой файла

Я ищу простой способ узнать размеры файлов, которые я планирую загрузить, еще не загружая их. В основном я создаю пакет файлов, которые необходимо загрузить, и было бы очень полезно, если бы я мог заранее определить, насколько велика будет общая нагрузка.

объект Loader во flash имеет свойство totalBytes, но оно возвращает значение только тогда, когда вы уже загружаете файл.


person Kasper    schedule 01.03.2009    source источник


Ответы (6)


Под загруженным вы имеете в виду полностью загруженный или без вызова загрузки? Если вызов загрузки приемлем, может оказаться полезным следующее. Событие прогресса дает общий размер входящих данных при первом срабатывании. Мы просто запускаем данное событие прогресса, берем общее значение текущего загружаемого элемента и добавляем его к нашей собственной переменной _total; Мы продолжаем это до тех пор, пока наш поставщик данных (массив, xml и т. д.) не станет пустым. к концу у вас есть сумма всех ваших активов.

package
{
    import flash.display.Sprite;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.events.ProgressEvent;
    import flash.URLLoader;
    import flash.URLRequest;

    public class ExampleDocumentClass extends Sprite
    {
        private var _urlLoader:URLLoader;
        private var _loader:Loader;
        private var _request:URLRequest;
        private var _total:Number;
        private var _array:Array;

        public function ExampleDocumentClass():void
        {
            if(stage) _init;
            else addEventListener(Event.ADDED_TO_STAGE, _init);
        }
        private function _init(e:Event = null):void
        {
            _array = [{type:"nonDisplay", path:"path/to/file"},{type:"display", path:"path/to/file"}];
            _urlRequest = new URLRequest();

            //Non display asset
             _urlLoader = new URLLoader();
            _urlLoader.addEventListener(ProgressEvent.PROGRESS, _onProgress);

            //Display asset
            _loader = new Loader();

            loadAsset();
        }
        private function loadAsset():void
        {
            if(_array.length > 0)
            {
                var pObj:Object = _array[0];
                if(pObj.type == "nonDisplay")
                {
                    loadNonDisplayAsset(pObj.path);
                }
                else
                {
                    loadDisplayAsset(pObj.path);
                }
                //Remove this item from the array;
                _array.shift();
            }
        }
        private function loadNonDisplayAsset(pAsset:String):void
        {
            _urlRequest.url = pAsset;
            _urlLoader.load(_urlRequest);
        }
        private function loadDisplayAsset(pAsset:String):void
        {
            _urlRequest.url = pAsset;
            _loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, _onProgress);
            _loader.load(_urlRequest);
        }
        private function _onProgress(e:ProgressEvent):void
        {
            _total += e.bytesTotal;
            _loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, _onProgress);
            _urlLoader.removeEventListener(ProgressEvent.PROGRESS, _onProgress);
        }
    }
}

Таким образом, мы загружаем актив ровно настолько, чтобы добавить его итоговый размер к нашей собственной переменной _total, а затем мы вызываем следующий элемент в массиве и добавляем его итоговое значение до тех пор, пока поставщик данных не станет пустым. Очевидно, это можно сделать с помощью XML, или, как вам угодно, массив — это именно то, что я использовал для упражнения.

person Brian Hodge    schedule 02.03.2009
comment
Звучит как довольно хорошее решение. Не так чисто, как хотелось бы (избегая вызовов загрузки). Но это сработает. Спасибо! - person Kasper; 04.03.2009
comment
URLLoader и Loader необходимы для доступа к требуемым данным, и если вы тщательно очищаете и/или повторно используете своих слушателей, удаляя окончательный вариант, я не вижу ничего плохого в реализации. Спасибо за хороший вопрос. Удачи! - person Brian Hodge; 04.03.2009

Невозможно получить размер файла раньше из Actionscript 3. Простым решением было бы добавить на сервер небольшой скрипт, который сканирует все файлы и возвращает их имена и размер в swf (как JSON или XML или что-то еще).

person TheHippo    schedule 01.03.2009

В ActionScript этого сделать нельзя. Для этого вам понадобится код на стороне сервера. Вы можете создать метод, который принимает имя файла и возвращает общее количество байтов.

person Christophe Herreman    schedule 01.03.2009

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

person gargantuan    schedule 01.03.2009

Другим (вероятно, излишним) способом было бы создать что-то, что просто запрашивает у сервера заголовки файла (включая размер файла). То же самое может быть достигнуто, просто начав загрузку файла и закрыв поток, когда у вас есть размер файла (должно быть довольно быстро), или используя (как предлагалось ранее) какой-либо другой способ запросить у сервера размер файла (полезно, если вы загружаете несколько файлов и вам нужно знать размер файла перед загрузкой)

person Antti    schedule 02.03.2009

Я экспериментировал с методом, предоставленным Брайаном Ходжем, а также с другим методом, в котором я отправлял переменные (расположение папок в виде строк из XML) в PHP, чтобы получить объединенный размер всех файлов в определенной папке и вернуть данные в Вспышка.

Одна из основных проблем, с которыми я столкнулся на пути к раю предварительной загрузки, заключалась в том, что Flash Player, похоже, выдает противоречивые результаты в отношении размера файла! Даже если бы я загружал одни и те же файлы дважды, Flash сообщал мне, что они были разного размера... иногда.

Это также вызвало проблемы с альтернативным (PHP) методом, поскольку PHP-скрипт выдавал (по-видимому) точные результаты размера файла, которые не соответствовали результатам, полученным Flash, в результате чего мой загрузчик переходил на 85% или 128%, в зависимости от кэширования и Настроение Флэша :/

Я отказался от обоих методов в пользу хорошего класса под названием bulk-loader, который позволяет для загрузки в очередь и отслеживания прогресса нескольких элементов и многое другое :D

Просто имейте в виду, что это значительно увеличит размер вашего swf-файла... как это ни парадоксально

person munkychop    schedule 20.04.2010