Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Один загрузчик для текста и картинок (http://www.flasher.ru/forum/showthread.php?t=214385)

djken 11.07.2017 22:50

Один загрузчик для текста и картинок
 
Всем привет.
Хочу написать класс, который смог бы загружать JSON и картинки JPG, PNG. Подскажите пожалуйста, как бы это правильней реализовать? Готовые решения типа менеджеров загрузки не интересуют.

Как я полагаю, при окончании загрузки мне полученные данные нужно складывать в какой-нибудь контейнер data:* и оттуда забирать по окончанию события? Как правильнее сделать, т.к. загружаемые данные разных типов... И Loader не сможет забирать, если будут приходить текстовые данные - получается мне перед этим нужно проверять расширение файла?

Так вот начал:
Код AS3:

package
{
        import flash.display.Loader;
        import flash.events.Event;
        import flash.events.HTTPStatusEvent;
        import flash.events.IOErrorEvent;
        import flash.net.URLLoader;
        import flash.net.URLLoaderDataFormat;
        import flash.net.URLRequest;
        import flash.system.LoaderContext;
 
        public class MainLoader
        {
                private var _urlLoader:URLLoader;
                private var _loader:Loader;
                public var data:*;
 
                public function MainLoader(url:String)
                {
                        _urlLoader = new URLLoader();
                        _urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
                        _urlLoader.addEventListener(Event.COMPLETE, onBinaryLoadCompleteHandler);
                        _urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onBinaryIOErrorHandler);
                        _urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onBinaryHTTPStatusHandler);
                        _urlLoader.load(new URLRequest(url));
                }
 
                private function onBinaryHTTPStatusHandler(e:HTTPStatusEvent):void
                {
                }
 
                private function onBinaryIOErrorHandler(e:IOErrorEvent):void
                {
                }
 
                private function onBinaryLoadCompleteHandler(e:Event):void
                {
                        _loader = new Loader();
                        var context:LoaderContext = new LoaderContext();
                        context.allowCodeImport = true;
                        _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadCompleteHandler);
                        _loader.loadBytes(e.currentTarget.data, context);
                }
 
                private function onLoadCompleteHandler(e:Event):void
                {
                        trace('COMPLETE!');
                }
        }
}


alexandrratush 12.07.2017 10:36

Вариантов как это сделать много. Если вас не интересуют готовые решения, то хотя бы посмотрите на гитхабе как они работают.

Tails 12.07.2017 10:37

Цитата:

Готовые решения типа менеджеров загрузки не интересуют.
Почему? Если они делают именно то, что вы описываете, оттестированы и проверены. В крайнем случае, можно слегка переписать их, добавив необходимый функционал или поменяв апи. Это гораздо проще и быстрее, чем делать с нуля, потом тестировать и т.д.
https://github.com/Gamua/Starling-Fr...ssetManager.as

djken 12.07.2017 17:00

Потому что хочу разобраться. Да и задача стоит не сложная. Сейчас в моем приложении работают и URLLoader для загрузки JSON. И Loader для подгрузки картинок. И просто хочу вынести их в отдельный класс. Не хочу использовать менеджер с кучей лишнего функционала. Да и свой класс мне всегда проще усовершенствовать либо найти ошибку.

Поэтому столкнулся с этими вопросами:
1) как определить тип получаемого файла? По первым битам, HTTP заголовки? Могу конечно просто в MainLoader передавать некий идентификатор, что сейчас вот гружу картинку, а сейчас json.. Но считаю правильней было бы, если загрузчик сам определял тип

2) каким образом класс должен отдавать данные разного типа, если это может быть картинка либо json ?

undefined 12.07.2017 18:07

Цитата:

1) как определить тип получаемого файла?
Никак не определить.Это может быть json, у которого первые n байт совпадают с хидером джипега.Только если mime type читать, но он может и наврать к тому же для локальных файлов не подходит.Поэтому остается только как в менеджере старлинга - по расширению.
Цитата:

2) каким образом класс должен отдавать данные разного типа
Например через класс-обертку:
Код AS3:

public class ContentData{
    public var json:Object;
    public var bmp:BitmapData;
}


caseyryan 13.07.2017 13:22

Цитата:

Никак не определить.Это может быть json, у которого первые n байт совпадают с хидером джипега.
Очень маловероятно.
Вот к примеру (это класс из утилит Dragon Bones), как можно отпределить типы картинок и zip. Мне нужен был зип, и я добавил туда байты зипа из спецификации. То же самое можно сделать и для других типов файлов. Достаточно найти спецификацию типа и посмотреть что у него пишется в хэдэр.
Код AS3:

package 
{
        import flash.utils.ByteArray;
 
 
        public class BytesType
        {
                public static const SWF:String = "swf";
                public static const PNG:String = "png";
                public static const JPG:String = "jpg";
                public static const ATF:String = "atf";
                public static const ZIP:String = "zip";
 
                public static function getType(bytes:ByteArray):String
                {
                        var type:String;
                        var b1:uint = bytes[0];
                        var b2:uint = bytes[1];
                        var b3:uint = bytes[2];
                        var b4:uint = bytes[3];
                        if ((b1 == 0x46 || b1 == 0x43 || b1 == 0x5A) && b2 == 0x57 && b3 == 0x53)
                        {
                                //CWS FWS ZWS
                                type = SWF;
                        }
                        else if (b1 == 0x89 && b2 == 0x50 && b3 == 0x4E && b4 == 0x47)
                        {
                                //89 50 4e 47 0d 0a 1a 0a
                                type = PNG;
                        }
                        else if (b1 == 0xFF)
                        {
                                type = JPG;
                        }
                        else if (b1 == 0x41 && b2 == 0x54 && b3 == 0x46)
                        {
                                type = ATF;
                        }
                        else if (b1 == 0x50 && b2 == 0x4B)
                        {
                                type = ZIP;
                        }
                        return type;
                }
        }
}

Тебе нужно грузить простым URLLoader'ом с типом BINARY, а потом загруженный байт массив передавать в в этот метод, чтобы определить тип.
Профит.

п.с. Но самый простой способ определить - это просто использовать расширение.

djken 13.07.2017 15:18

Цитата:

п.с. Но самый простой способ определить - это просто использовать расширение.
Да, это был бы отличный вариант, но многие ссылки с которыми работаю не имеют расширений - с внутренней переадресацией.

За пример спасибо! Поэксперементирую :)

А вот как распознать json, xml ?.. это ведь текстовые файлы. Полагаю, тут скрипт должен анализировать структуру.. Либо парсером проходить - если ошибки нет, то формат верный. Но, думается, этот вариант не очень хороший.

Nooob 13.07.2017 23:19

Цитата:

Сообщение от djken (Сообщение 1201188)
А вот как распознать json, xml ?

Исключить вначале символы " ","\n","\r" (байты 0x20 0xa 0xd) затем для Json вначале будет символ "{" или "[" (0x7b 0x5b) у XML "<" (0x3c), либо в заголовке ответа ожидать нужный Content-Type application/json, application/xml если все правильно сделано на стороне раздачи
а вообще знание о том что это за файл есть из контекста использования, странно предполагать что получив json ты попытаешься засунуть его в Bitmap. передавай загрузчику url и тип того что ты хочешь получить, излишняя адаптивность багоемка.
В идеале нужно абстрагировать контент от менеджера загрузок, использовать один менеджер который всегда загружает байты(URLLoader) и отдает их абстрактному контенту/интерфейсу(IContent), где конкретный контент инстанцирован тобой(в нужном/ожидаемом контексте) и этот конкретный контент(PNGContent,JSONContent,XMLContent,SoundContent) уже решает(и знает) что с байтами делать, если text/json/xml readUTFBytes, если картинка Loader.loadBytes. итого поверх этого проще запилить кэширование, пулинг, сохранение в SharedObject и в памяти будет меньше весить при неиспользуемом состоянии и это все при глобальном контроле загрузок(очередь по приоритетам, ограничение по одновременной загрузке, отмена загрузок)


Часовой пояс GMT +4, время: 03:16.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.