Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > Идиотизмы

Даже в определениях идиотизма встречается идиотизм.
Цитата:
Идиотизм — устаревшее название идиомы
Идиома в программировании — понятие близкое к понятию шаблона проектирования. Идиомы представляют собой шаблоны проектирования, учитывающие специфику конкретного языка программирования и потому не универсальные. Это хорошие решения проектирования для конкретного языка или программной платформы.
Рейтинг: 5.00. Голосов: 2.

Идиотизмы: Socket

Запись от BlooDHounD размещена 23.04.2010 в 14:34
Обновил(-а) BlooDHounD 07.06.2010 в 17:11

для понимания материала необходимы следующие знания:
flash.net.Socket
Подключение к сокетам




ну вот за что флэшерам такие мучения? Socket, казалось, ну что можно сломать в таком примитивном классе? анннет.
и так.
1. мы пытаемся законектися.
2. допустим наш сервер лежит.
3. нам само сабой вываливается ioError.
4. мы, узнав о такой трагедии, расстраиваемся и отписываемся от всех событий.
5. получаем unhadled securityError, так как policy-file нам тоже не удалось получить.

замечательно! вот только с откуда я могу знать, что после ioError я 100% получу securityError? а если у меня на 843 порту ещё один демон болтается? мне на всегда события оставлять висеть? до здравствуют утечки?

исправленный класс Socket:
Код AS3:
package blooddy.patch.net {
 
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.Socket;
 
	/**
	 * @author					BlooDHounD
	 * @version					1.0
	 * @playerversion			Flash 9
	 * @langversion				3.0
	 */
	public class Socket extends flash.net.Socket {
 
		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------
 
		/**
		 * @inheritDoc
		 */
		public function Socket(host:String=null, port:int=0.0) {
			super( host, port );
			super.addEventListener( Event.CLOSE,						this.handler_close, false, int.MAX_VALUE, true );
			super.addEventListener( IOErrorEvent.IO_ERROR,				this.handler_error, false, int.MAX_VALUE, true );
			super.addEventListener( SecurityErrorEvent.SECURITY_ERROR,	this.handler_error, false, int.MAX_VALUE, true );
		}
 
		//--------------------------------------------------------------------------
		//
		//  Variables
		//
		//--------------------------------------------------------------------------
 
		/**
		 * @private
		 */
		private var _hasError:Boolean = false;
 
		//--------------------------------------------------------------------------
		//
		//  Overrided methods: Socket
		//
		//--------------------------------------------------------------------------
 
		/**
		 * @inheritDoc
		 */
		public override function connect(host:String, port:int):void {
			super.connect( host, port );
			this._hasError = false;
		}
 
		/**
		 * @inheritDoc
		 */
		public override function close():void {
			super.close();
			this._hasError = true;
		}
 
		//--------------------------------------------------------------------------
		//
		//  Event handlers
		//
		//--------------------------------------------------------------------------
 
		/**
		 * @private
		 */
		private function handler_close(event:Event):void {
			this._hasError = true;
		}
 
		/**
		 * @private
		 */
		private function handler_error(event:ErrorEvent):void {
			if ( this._hasError ) {
				// ошибка уже была. поэтому блокируем остальные
				event.stopImmediatePropagation();
			} else {
				this._hasError = true;
				// надо оптисаться, что бы не мешать вызову исключения
				super.removeEventListener( event.type, this.handler_error );
				if ( !super.hasEventListener( event.type ) ) {
					// если подписчиков нету, диспатчим ошибку, что бы вывалился unhadled securityError
					super.dispatchEvent( event );
				}
				// подписываемся обратно
				super.addEventListener( event.type, this.handler_error, false, int.MAX_VALUE, true );
			}
		}
 
	}
 
}
Всего комментариев 60

Комментарии

Старый 23.04.2010 16:31 iNils вне форума
iNils
 
Аватар для iNils
Цитата:
допустим наш сервер лежит.
разве это повод делать это?
Цитата:
мы, узнав о такой трагедии, расстраиваемся и отписываемся от всех событий.
Старый 23.04.2010 16:32 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
конечно. нечего держать сокет в памяти. вывалили сообщение юзеру и удали весь контроллер с сокетом.
Старый 23.04.2010 16:46 iNils вне форума
iNils
 
Аватар для iNils
Так сервер может очухаться через минуту или через 5.
Можно пойти тремя путями:
1. Переключиться на другой "канал" обмена данными. Тогда да, тут это нужно.
2. Ждать до упора, то есть время от времени пытаться подконнектиться.
3. Делаем пункт 1, но при этом не прекращаем попыток пункта 2 и при удаче переходим на сокет.
То есть, в 2 из 3 случаев отписываться не надо. А оставшийся, на мой взгляд не очень хороший подход, пункт 3 мне больше нравится.
Обновил(-а) iNils 23.04.2010 в 16:58
Старый 23.04.2010 16:56 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
ну обычно так и происходит. просто мне в любом случаи не нужно 2 ошибки от одного сокета. и мне совершенно не надо показывать пользователю 2 ошибки. если я оставлю висеть хэндлеры, то сработают оба, если удалю то вывалится unhadled erroEvent на одно из них. так что без хака в том или ином виде не обойтись.
Старый 23.04.2010 17:01 iNils вне форума
iNils
 
Аватар для iNils
То есть тебя не устраивает, что ты не только получаешь IOErrorEvent.IO_ERROR, но SecurityErrorEvent.SECURITY_ERROR после?
Старый 23.04.2010 17:21 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
угу. именно так я и написал =)
Старый 23.04.2010 17:22 iNils вне форума
iNils
 
Аватар для iNils
Возможно в этом есть какой-то смысл, который мы пока не видим?
Старый 23.04.2010 17:26 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
ага. истина где-то рядом =) это не про adobe
Старый 30.11.2010 19:54 alatar вне форума
alatar
 
Аватар для alatar
Ну в принципе такое поведение выглядить логичным (хотя не становится от этого менее идиотским). Сокет ломится на 843-й порт, обламывается (сервер ведь лежит) и выдает IO_ERROR, но дальше согласно докам он должен проверить целевой порт на предмет файла политики (раз с 843-м не вышло). Снова обламывается и выдает SECURITY_ERROR.
Странно, что повторно не выскакивает unhadled ioError, но видимо IO_ERROR не отправляется повторно, либо секюрити возникает раньше.
Старый 30.11.2010 21:53 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
от того что 843 порт закрыт, у вас не будет вываливаться IO_ERROR. так что ваша логика не имеет отношения к реальным вещам.
Старый 30.11.2010 23:02 alatar вне форума
alatar
 
Аватар для alatar
Цитата:
2. допустим наш сервер лежит.
Я имел ввиду эту ситуацию.
Старый 30.11.2010 23:58 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
и? ioError вываливается не из-за того что закрыт 843 порт.
Старый 11.04.2011 16:53 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Кстати, обрати внимание на тип первого параметра DataOutput.writeBytes()
Я ток что обламался так неплохо...
Старый 11.04.2011 22:00 dimarik вне форума
dimarik
 
Аватар для dimarik
ByteArray первым параметром идет. В чем проблема возникла?
Старый 11.04.2011 22:06 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
А то, что по логике, там должен был быть IDataInput - и я так пролетел пытаясь записать в сокет, который в функцию передавал как DataInput. Пришлось левый ByteArray добавлять, чтобы сначала в него прочитать, а потом уже в сокет.
Старый 12.04.2011 03:17 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
там по логике должен быть ByteArray. данные должны быть вычитаны, а вычитываются они только в ByteArray. так как только туда и писать и читать. записывать в IDataInput не имеет смысла.
Старый 12.04.2011 09:47 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Объясняю на пальцах: у тебя есть 2 сокета, ты хочешь прочитать из одного 12345 байтов в другой: сделай это не создавая ByteArray и так, чтобы при этом не нужно было читать по одному байту.
ЗЫ. Я мог перепутать read / write и input / output - т.как названия дурацкие, и я в них все время путаюсь, но смысл должен быть понятен.
ЗЫЫ. Да, должен быть IDataOutput, а не IDataInput, и сооветственно IDataInput должен читать из другого IDataInput, а не только массива.
Старый 12.04.2011 12:19 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
я не знаю как объяснить, но ты не прав. основной смысл в том, что из IDataOutput нельзя прочитать данные. а значит записывать их туда бессмысленно с точки зрения сокета.
Старый 12.04.2011 13:30 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
А какая ему разница можно или нельзя прочитать? Он же не читать, а писать собирается. Вот представляешь, в других языках это вполне типичное явление, что потоки могут быть либо только для чтения, либо только для записи, либо и то и то. И тем не менее, интерфейс у них - интерфейс потока. В худшем случае, если ты поломишся писать в поток, который только для чтения - получишь ошибку (но тебе еще извратися нужно будет, чтобы как-то это сделать). Тем не менее, если ты можешь писать в поток, то ты можешь писать и в вирутальный поток в памяти, и в строку, и в файл, и все это делать используя одни и те же методы, не создавая дополнительных прослоек между записью и чтением.
Представь тебе нужно скопировать файл в операционной системе - ты, по-нормальному, откроешь один поток, и сразу же будешь писать в другой, а не кешировать весь файл в памяти, пока не дочитается, а потом писать в место назначения - ты так большие файлы просто никогда не скопируешь, памяти не хватит.
Старый 12.04.2011 14:14 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
у нас нет потоков. кстати копирование в системе происходит через кэширование в памяти.
Старый 12.04.2011 15:54 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Ну и что, что нет потоков? Я это как аналогию привел - запись в поток только для записи, или копирование в dev/nul - это что по твоему? Ты ведь никогда не сможешь прочитать из потока только для записи - исходя из того, что ты говоришь, так туда и писать не нужно, аналогично dev/nul - а зачем туда копировать, если потом оттуда уже не достать? Вот, бывают такие ситуации, когда нужно записать и не читать больше. В данном случае мне абсолютно не понятно, почему записывать можно вдруг только в ByteArray, а в FileStream - нет, при том, что по одному байту, или там по 2-4 можно, и даже можно неограниченое количество, но только если строка, а вот просто байты - нет. Где ты в этом логику видишь?
"Кешируется" - это пишется в буффер, и естественно не кешируется все именно по той причине, что я только что описал - если бы ты кешировал весь файл, то ты бы некоторые файлы физически не смог бы скопировать, т.как не хватило бы места.
Старый 12.04.2011 16:03 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
а тебя заставляют в сокете буферизировать "всю" информацию? или только пакет? записывать используя интерфейс нельзя как минимум из-за того, что способ записи не определён. а там чётко тебе возвращают именно ByteArray. ровненько те данные, которые были присланы, в независимости от endian и прочей бадяги. делай с ними что хочешь. считай, что тебе вернули "byte[]". то что ByteArray имеет интерфейсы записи и чтения никакого значения не имеет. они не используются.
Старый 12.04.2011 16:54 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Так почему не используются? Я же именно это и спрашиваю? Почему у нормальных людей это тривиальная процедура, а сделать это на флеше можно только через задний проход, да еще и у компьютера трагедия случится, если случайно прочитать, как ты предлагаешь, файл на несколько десятков мегабайт, частями, кешируя его силами AS в одном единственном треде... это развлечение ток для тех, кто ищет повод свалить перекурить
Старый 12.04.2011 17:21 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
не хочу тебя расстраивать, но всё так устроено. всё буферизируется в памяти сперва. и у всех это через задний проход. если есть какие-то реализации в других языках, то я их поздравляю. ас на столько не уникален, что я даже не знаю как тебе передать на сколько.
Старый 12.04.2011 17:55 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Все нормальные языки на "высоком" уровне офромляют запрос к D-Bus или похожему сервису и он занимается копированием. Это если мы говорим о файловой системе / копировании файлов.
В Шарпе это нормально прочитать из потока и тут же записать в другой http://msdn.microsoft.com/en-us/library/dd782932.aspx обрати внимание. Я так предполагаю, что в Яве тож наверное до этого додумались, ну и т.п. Это тривиальная задача которая возникает практически в любом более-менее большом десктопном приложении, тут как бы даже спорить странно...
Старый 12.04.2011 19:35 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
ну они молодцы. заменили класс ByteArray на класс Stream. что-то интерфейсом и там не пахнет ...
просто из-за синхронности они в следующей строчке могут сразу заполучить вычитанный полностью стрим.
Обновил(-а) BlooDHounD 12.04.2011 в 19:38
Старый 12.04.2011 19:39 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
и ещё я не понял какая разница, кто буферизирует данные, D-Bus или кто-то ещё, если это всё равно происходит.
Старый 12.04.2011 21:13 dimarik вне форума
dimarik
 
Аватар для dimarik
Я за идею Олега. Очень здраво.
Старый 12.04.2011 21:15 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
ну перестроить мир очень легко =) всё в ваших руках.
Старый 12.04.2011 21:16 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
к тому же если вам очень припёрло, то есть такая штука как наследование. допишите и наслаждайтесь.
Старый 12.04.2011 22:56 dimarik вне форума
dimarik
 
Аватар для dimarik
ByteArray реализует IDataOutput. Откидываем все эти методы, иначе парни из адобе сделали бы первый параметр типа IDataOutput. Придержим пока методы IDataInput. Что имеем в остатке в ByteArray?

1) [] (доступ к массиву)
2) length
3) position

Теперь расскажите мне, почему в методе writeBytes() сокета нужны эти свойства входного потока?
Старый 12.04.2011 23:22 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
ОК, почему делать это во флеше - не правильно.
Флеш - это managed runtime + persistent type information + еще куча всего-всего, что тебе просто не нужно, когда ты копируешь один файл в другой. Это значит, что когда ты работаешь во флеше, то рантайм делает кучу проверок, которые можно было бы не делать, если отдать ту же процедуру на выполнение сервису, который только ее и умеет делать, но зато очень хорошо (и этому сервису не нужно за каждым байтом записывать еще кучу байтов по-сути метаданных). Точно по той же причине и в Шарпе есть специальная функция для копирования из потока в поток - потому что если делать это непосредственно в самом Шарпе - ты будешь напрягать этим мусорщика по чем зря (он же буффер будет пихать в кучу), чтобы поддерживать возможность рефлексии все байты в буффере будут пронумерованы, получат айдишники и т.п.
Но еще хуже то, что флеш работает в одном потоке. Это значит, что если ты захочешь скопировать большой файл тебе нужно будет его лочить, и на долго, твоя программа либо просто замрет, либо, если ты будешь пытаться делать это по таймеру - будет жутко тормозить.

Как я наследованием решу проблему отсутсвия native API? Тут ток разве что плеер патчить, наследование тут как бы уже ничем не поможет Меня же напрягает не отсутствие возможности как таковой, а то, что я вынужден реализовывать используя изначально плохие инструменты.
Старый 13.04.2011 03:00 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
Цитата:
Сообщение от wvxvw
ОК, почему делать это во флеше - не правильно.
Флеш - это managed runtime + persistent type information + еще куча всего-всего, что тебе просто не нужно, когда ты копируешь один файл в другой. Это значит, что когда ты работаешь во флеше, то рантайм делает кучу проверок, которые можно было бы не делать, если отдать ту же процедуру на выполнение сервису, который только ее и умеет делать, но зато очень хорошо (и этому сервису не нужно за каждым байтом записывать еще кучу байтов по-сути метаданных).
ничего не ясно.
Цитата:
Сообщение от wvxvw
Точно по той же причине и в Шарпе есть специальная функция для копирования из потока в поток - потому что если делать это непосредственно в самом Шарпе - ты будешь напрягать этим мусорщика по чем зря (он же буффер будет пихать в кучу), чтобы поддерживать возможность рефлексии все байты в буффере будут пронумерованы, получат айдишники и т.п.
ога. тока в шарпе stream и есть тот самый буфер.
Цитата:
Сообщение от wvxvw
Но еще хуже то, что флеш работает в одном потоке. Это значит, что если ты захочешь скопировать большой файл тебе нужно будет его лочить, и на долго, твоя программа либо просто замрет, либо, если ты будешь пытаться делать это по таймеру - будет жутко тормозить.
ты в курсе, что чтение файлов и прочая бодяга работает в отдельных потоках? а всякие загрузщики диспатчат прогресс, поэтому размер буфера во флэше обычно небольшой +/-64кб. собственно сокет тоже необязательно за раз тебе все посланные данные выплюнет.
Цитата:
Сообщение от wvxvw
Как я наследованием решу проблему отсутсвия native API? Тут ток разве что плеер патчить, наследование тут как бы уже ничем не поможет
я не очень врубаюсь какой nativeAPI тебе надо для написания буфера?
Цитата:
Сообщение от wvxvw
Меня же напрягает не отсутствие возможности как таковой, а то, что я вынужден реализовывать используя изначально плохие инструменты.
инструменты нормальные. просто они асинхронны.

я не понимаю тебя. хочешь я тебе напишу это волшебный кусок с наследованием? я знаю что в джаве этот кусок написан на джаве. с шарпом скорее всего тоже самое. и да, я ж надеюсь ты понимаешь что stream в шарпе это не тоже самое, что и файл? и не тоже самое, что сокет? это подобие что-то типа нашего ByteArray. просто увы наши потоки не синхронны.
Старый 13.04.2011 03:02 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
dimarik, ByteArray реализует эти интерфейсы для твоего дополнительного удобства. на самом деле в первую очередь он является обычным массивом байт. тобишь обычный byte[].
Старый 13.04.2011 03:26 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
чет ты все попутал... но ты это делаешь просто из упрямства и нежелания вдуматься в то, что я тебе пытаюсь сказать. byte[] - это объект высокоуровнего языка, он хранит информацию о своем типе, методах, находится в стеке, который можно опять же через рефлекшн получить, и еще много-много всего разного, что тебе дает удобный рантайм типа .NET или Java. Но все эти плюшки дорого стоят. Это не так заметно, когда тебе нужно работать с небольшим объемом информации, но когда его становится на несколько порядков больше - то за каждую такую плюшку тебе удушиться захочется.
Вот смотри, я оставлял сокет за работой на ночь + strace. Пришел сегодня разобрать логи, и смотрю что флеш, например, помимо всего прочего при каждой записи байта в ByteArray ломится в кернел за системным временем! Вот тебе прелесть менеджед рантайма - вот ты не знал, а оказывается инфа о том, когда ты записал _каждый_ байт записывается, сохраняется во временную память и выбрасывается через пару миллисекунд рантаймом потому что никому не нужна (получение даты на самом деле мелочь, там еще предстоит найти, кто именно отбирает кучу процессорного времени). Вот этого я и хочу избежать имея нативные API для записи в поток. Флеш не пишет в поток и не пишет в память сам, он вызывает 100500 функций по дороге, чтобы логировать чего-то, чего-то проверять и т.д. и т.п. Это занимает тучу времени. По сравнению с другим, таким же менеджед рантаймом - SBCL, но в котором есть возможность писАть в поток флеш нагревает одно из ядер ЦПЮ в 100 раз больше. Я не проверял на других процессорах / другой архитектуре, но осмелюсь предположить, что если бы проц был не какой-то стремный второсотрный интел-для-офиса, он все равно сожрал бы 100% от одного ядра. Но виноват в этом не столько сам флеш, сколько отсутсвие необходимых native API которые могли бы оптимизировать запросы к дате, например, да и еще оставшиеся сотни 2-3 запросов к системным библиотекам, которые там сто лет в обед не были нужны, а существуют только для того, чтобы на более высоком уровне тебе обеспечить метаданные о работе твоего приложения.
Старый 13.04.2011 03:41 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
у меня нет слов =) смешались в кучу люди, кони ... я даже не знаю в чём я упрямлюсь, если из нас двоих от первоначальной темы удалился ты, причём максимально возможную дистанцию моей некомпетентности. вместо рассуждений научи меня в сях читать файл без буфера =) у нас вопрос буфера стоял изначальный? ты же хочешь сэкономить процессорное время тем, что флэш будет делать bytes.writeByte( value ) вместо bytes[i] = value? исходя из твоих суждений именно этим мы и сэкономим процессорное время добавил 100500 вызовов чёртки-каких методов =)
Обновил(-а) BlooDHounD 13.04.2011 в 03:57
Старый 13.04.2011 12:26 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Нет, флеш не будет делать никаких byte[i] = x или writeByte() точно так же, как не делает этого, когда загружает чего-нибудь используя URLLoader например в свойство data. И это потому, что делать буфер во флеше - это все равно, что на бумажке в клеточку записывать байты, а потом их переписывать туда, куда ты их копировал. Это не просто непродуктивно, это мега-непродуктивно. Т.е. накладыне расходы флеша при копировании содержания файла из потока в поток несоизмеримо больше непосредственно самой операции (возможно в сотни или тысячи раз). Вот поэтому невозможность скопировать произвольное количество байт из IDataInput в другой IDataOutput - это, ну например для AIR - кирпич на дороге. Такую операцию, как разбор логов (которых могут быть сотни мегабайт) AIR просто не в состоянии будет выполнить в приемлимые сроки.

ЗЫ. Когда ты в сях читаешь файл, то ты тоже обращаешься к какой-то системной библиотеке, которая уже работает с памятью, девайсами и т.п. Она же и предоставляет API для записи в буфер. Но если бы тебе не нужно было прочитать весь файл, а например, определить есть ли в нем нужная строка, и если есть, записать в другой файл - вот тут тебе бы и понадобилось максимально быстро переписать кучу байт из одного потока в другой. И тебе бы в _твоей_ программе буфер был бы б данном случае абсолютно ни к чему. Ты бы мог отдать это на выполнение системной библиотеке, которая умеет это делать наверняка лучше, чем ты бы сделал.
Старый 13.04.2011 13:00 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
Цитата:
Сообщение от wvxvw
Нет, флеш не будет делать никаких byte[i] = x или writeByte() точно так же, как не делает этого, когда загружает чего-нибудь используя URLLoader например в свойство data. И это потому, что делать буфер во флеше - это все равно, что на бумажке в клеточку записывать байты, а потом их переписывать туда, куда ты их копировал. Это не просто непродуктивно, это мега-непродуктивно. Т.е. накладыне расходы флеша при копировании содержания файла из потока в поток несоизмеримо больше непосредственно самой операции (возможно в сотни или тысячи раз).
мне кажется что ты с другой планеты. сейчас в ByteArray данные записываются миную интерфейсы. будем считать что там вызывается bytes[i] = value.
Цитата:
Сообщение от wvxvw
Вот поэтому невозможность скопировать произвольное количество байт из IDataInput в другой IDataOutput - это, ну например для AIR - кирпич на дороге.
я могу скопировать произвольное количество бай используя ByteArray, не знаю какие у тебя сложности с этим.
Цитата:
Сообщение от wvxvw
ЗЫ. Когда ты в сях читаешь файл, то ты тоже обращаешься к какой-то системной библиотеке, которая уже работает с памятью, девайсами и т.п. Она же и предоставляет API для записи в буфер. Но если бы тебе не нужно было прочитать весь файл, а например, определить есть ли в нем нужная строка, и если есть, записать в другой файл - вот тут тебе бы и понадобилось максимально быстро переписать кучу байт из одного потока в другой. И тебе бы в _твоей_ программе буфер был бы б данном случае абсолютно ни к чему. Ты бы мог отдать это на выполнение системной библиотеке, которая умеет это делать наверняка лучше, чем ты бы сделал.
какое это имеет отношение к вопросу? в сях я читаю файл в массив байт ( byte[] ), а потом записываю это дело в другой файл. делает это обычно блоками. размер ты указываешь сам.

и всё таки, как ты собираешься ускорить процесс чтения используя интерфейс? если будет юзаться интерфейс, то вся запись и чтение будут проходить через readByte() и writeByte(). это не просто слегка медленнее - это как сравнивать скорость перемещения реактивного самолёта и велосипеда.

мне кажется ты всё-таки хочешь многопоточность и класс Stream, просто ты почему зацепился за интерфейсы, и странно всё это объясняешь через какие-то системные модули, которые никакого отношения к нам не имеют. да и вообще не имеют никакого отношения к вопросу потоков и работы с бинарными данными.
Старый 13.04.2011 13:21 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Нет, ты не просто записываешь в массив byte[] - ты обращаешься к системной библиотеке, просишь заалочить сколько-то памяти + создать указатель на новую позицию в массиве, или, я толком не знаю даже всего, что именно подразумевет эта операция, эта библиотека идет в кернел и спрашивает, а какой интерфейс реализует шина, узнав интерфесй шины отправляет данные другой программе, драйверу, которая их уже будет размещать где-то в памяти (но на самом деле стадий больше, т.как нужно еще проверить кто автор запускаемого кода - безопасность, сохранить какие-то данные о стейте - на случай ошибки, а может нужно будет попросить выделить дополнительную память изза дефрагментации и т.д. и т.п.) Ты этого всего не видишь, когда делаешь byte[i] = x. Ты работаешь с интерфейсом языка высого уровня, абстракцией так сказать.
Точно так же флеш, когда будет записывать байт в массив байт - сделает очень много операций для того только, чтобы удовлетворить требованиям рантайма (рантайму нужно помнить информацию о типе объекта, текущей выполняемой функции и всех функциях которые привели к вызову данной функции, хранить стейт на случай ошибки, следить за правильной последовательностью выполнения, если протоколы реализующие работу не гарантируют таковой и еще очень и очень много всего. Ты можешь косвенно узнать какие сервисы флеш задействовал записывая байт в массив байтов используя, например, strace который позволяет логировать обращения к загруженым библиотекам и посмотреть, чем будет отличаться записывание байта в массив байт в Си и во Флеше
Ну просто сопоставь числа - ты можешь эмпирическим путем выяснить сколько времени занимает запись в ByteArray во флеше, ну и сравни это с показателями процессора, памяти и т.д. С твоей точки зрения "записать в массив байт - это почти то же самое, что просто записать в оперативную память", но ты можешь легко убедится, что это не так, просто потому, что если бы это было верно, то запись происходила бы на несколько порядков быстрее.
Старый 13.04.2011 14:19 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
wvxvw, ты какой-то бред несёшь. перечитай всё с самого начала. чего хотел ты в первых постах, и чего ты хочешь сейчас. у тебя спор ушёл в область полемики, где совершенно не говоришь по теме. я тебе это об этом говорю уже 4й пост, но ты ещё больше углубляешься в теологию. в общем совершенно потерял нить твоей мысли. всё что понял:
1. ты хочешь многопоточность
2. ты хочешь стрим ( мегасуперпуперстрим из шарпа, который всемогущ и супер быстр )
3. наличие IDataOutput в readBytes тебе побоку.
Обновил(-а) BlooDHounD 13.04.2011 в 14:58
Старый 13.04.2011 14:57 alexcon314 вне форума
alexcon314
Почитал, не удержался вклиниться, пардон.
Как-то я делал такой экперимент со свои расширением проектора:
Код:
var f:PFile = new PFile();
f.create("d:\\video\\vvv.avi");
var t:PFile = new PFile();
t.create("d:\\video\\vvv2.avi");
var size:uint = f.size;
var offset:uint = FlrunEx.MEMSIZEMAX/2;
for (var i:uint = 0; i < size; i += offset)
{
	var b:ByteArray = f.readBytes(offset);
	t.writeBytes(b);
				
}
var d:ByteArray = f.readBytes(size-i);
t.writeBytes(d);
f.close();
t.close();
Суть его сводилась к тому, чтобы посмотреть. как в АС можно, используя расширение, конечно, скопировать файл 1.5 Гб. Работа тут идет, как видите, через AS-класс ByteArray, он используется для передачи/прима данных от расширения. Перед отправкой каждый вызов пакуется еще дополнительно в AMF, в расширении распаковывается и т.д. Данные дальше просто отправляются в какую-то из апишных функций. Ничего сложнее RadFile()/WriteFile() из WIN API в расширении не используется. Ну и плюс накладные расходы на разные там проверки, обертки и пр.. По-сути, был реализован аналог синхронного чтения-записи с двумя файловыми стримами. Этот код, как он есть, подвесил проектор секунд на 40. Плохо? То что плеер нереспонсился 40 сек. - безусловно, и это как раз следствие синхронности процесса взаимодействия с расширением плюс однопоточность исполнения АС. Что хорошо? То что такой же пример с копированим, например в проводнике, занимает примерно то же время, да, не отличалось даже в разы. Само собой, там это вынесено в отдельный поток и система продожает работать как ни в чем не бывало.

К чему я все это говорю? Сдается, что при работе с файлами, традиционной, так скажем, т.е. через буфер, накладные расходы на обслуживание каких-то там writBytes() в АС - семечки. Что уж говорить про memory stream'ы... там вообще различия будут копеешные. Ну, а предмет спора - почему не сделали чтени-запись в ас как в c# (через нативы и т.п., о чем говорил Олег), это для ниши плеера на рынке приложений просто ни к чему, сейчас, вовсяком случае. С сокетами вопроса вообще не понял, там все асинхронно по определению. И еще, Олег, а ты не смешиваешь понятия stream (поток) и thread (тоже поток)?
ЗЫ. На чистом АС я так не пробовал, в АЙР, скажем, потому не судите строго
Обновил(-а) alexcon314 13.04.2011 в 15:03
Старый 13.04.2011 18:01 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Я не смешиваю... потоки с процессами, если чесно, не вижу где я что-то об этом говорил. Я вообще привел поток только как пример, когда нам может понадобиться только запись без чтения...
По поводу экспериментов со временем и т.п. Я говорю про занятость ЦПЮ. Да, я думаю, что разница по времени может быть незначительной, если ЦПЮ не особо занят, но когда ЦПЮ работает в режиме сервера для компиляции - тогда числа будут совсем другими... Т.е. у нас есть ограничение по времени не связаное с рантаймом, предположим, пропускная способность шины, или записи на диск - они в любом случае медленнее обращений к памяти / ЦПЮ, поэтому, в "обычном" режиме мы, возможно, ничего и не заметим.
Проблема оказывается тогда, когда, например, тебе нужно запустит одновременно несколько десятков процессов, которые бы читали и писали в / из файла... и вот тут числа будут расти совсем не линейно... Т.е. если проводник и флеш в данной ситуации скопировали файл за одно и то же время, но проводник при этом занял 0.1% от времени ЦПЮ, а флеш - 30%, то когда у тебя таких процессов станет не 1, а 100, проводник, по-прежнему, будет в состоянии чего-то скопировать, может еще даж музыка на фоне играть не перестанет а флеш станет в очередь до после-послезавтра, ну это в том случае, если его не пошлют с такими запросами

Чтобы было понятнее, о чем я говорю, приложил картинку. Красным цветом - процесс, где бежит флешевый [коннектящийся] сокет, синим цветом - процесс, где бежит лисп сокет [слушающий] (это даже не Си!). А вот как сейчас открыть еще двадцать таких процессов, хотя бы?...

Старый 13.04.2011 18:23 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
BlooDHounD:
Нет, мне не нужен стрим... я уже даже не знаю как еще сказать, я поток привел только как пример, когда запись нужна, а чтение - нет. Что мне нужно - нативные методы для копирования, например, файлов, а лучше, всего, что имплементит IDataOutput во все, что имплементит IDataInput. Мне все равно есть многопоточность или нет, я об этом вообще говорил только в контексте того, что изза того, что флеш, как и любой другой рантайм вынужденный хранить рантайм-информацию о типах, стеке вызовов и т.п. будет работать заметно менее эффективно, чем, например, системные утилиты, и поэтому, было бы неплохо, если нет возможности отдать эту работу системным утилитам, то, хотябы, выделить ее в отдельный процесс, чтобы не останавливать все остальное.
Старый 13.04.2011 18:48 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
wvxvw, я уже не знаю как ещё спросить: ну ты же понимаешь, что работа через методы интерфейса будет в 100 раз медленнее нежели это происходит сейчас?
и что в твоём понимании рантайм? это ты типа VM так обзываешь?
Обновил(-а) BlooDHounD 13.04.2011 в 19:04
Старый 13.04.2011 19:34 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Common Language Runtime (CLR) - вот в таком смысле, если речь о среде выполнения и Runtime Type Information (RTTI) - если речь о метаданных.
Работа через интерфейс может быть оптимизирована, потому, что если ты будешь читать сразу по много байт, то тебе не нужно будет каждую такую операцию логгировать, обеспечивать метаданными и т.п. Именно по этой причине в шарпе есть запись из потока в поток, например. А во флеше на сегодняшний день не существует возможности оптимизировать работу даже до более-менее вменяемых показателей.
Все на самом деле началось с того, что я делал автоматизированые тесты, и внезапно выяснилось, что флеш элементарно не в состоянии логгировать то, что в нем происходит, а те логи, которые от него можно получить ничего не отражают именно по причине неэффективности логгера.
Старый 13.04.2011 19:42 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
Цитата:
Сообщение от wvxvw
Common Language Runtime (CLR) - вот в таком смысле, если речь о среде выполнения и Runtime Type Information (RTTI) - если речь о метаданных.
кхм .. а какое отношение эти штуки имеют к АС?
Цитата:
Сообщение от wvxvw
Работа через интерфейс может быть оптимизирована, потому, что если ты будешь читать сразу по много байт, то тебе не нужно будет каждую такую операцию логгировать, обеспечивать метаданными и т.п.
о да. действительно!!! сейчас же readBytes и writeBytes занимаются мистикой.
Цитата:
Сообщение от wvxvw
Именно по этой причине в шарпе есть запись из потока в поток, например. А во флеше на сегодняшний день не существует возможности оптимизировать работу даже до более-менее вменяемых показателей.
ога. я так и подумал. у нас есть запись из ByteArray в ByteArray. что тебя не устраивает?
Старый 13.04.2011 21:01 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
> кхм .. а какое отношение эти штуки имеют к АС?
Примерно такое же, как слова "плюс" или "функция".
> о да. действительно!!! сейчас же readBytes и writeBytes занимаются мистикой.
Нет, я уже замучался повторять, каждый вызов функции в рантайме, который должен обеспечить кучу дополнительного функционала, такого как учет, сохранение стейта, описание стека вызовов, хранение метаданных описывающих тип значений с которыми сейчас происходит работа - очень ресурсоемкий по сравнению с, например, системной, в которой не нужно хранить метаданные о типах, и т.п.
> ога. я так и подумал. у нас есть запись из ByteArray в ByteArray. что тебя не устраивает?
Опять же, я уже раз надцать ответил. Мне не нужно записывать в данной ситуации ничего в ByteArray. Мне нужно записать либо в сокет, либо в файл. При чем, нужно понимать, что и сокет и файл это не конечный пункт назначения, это класс, который оперирует (создает / открывает / закрывает / пишет) потоками. И вот так получилось, что эти классы (файл / сокет) не предоставляют нормального интерфейса для записи большого объема данных из одного в другой. Мне это кажется обычной недодлкой / недосмотром, на манер как Proxy класс, который обязывает использовать строки как ключи значений (при итерации), не смотря на то, что у рантайма на самом деле нет такого требования.
Старый 13.04.2011 22:27 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
ты кажется не можешь осознать что раз есть интерфейс, то всё общение с классом проходить должно через его методы. то есть у любого класса, даже MyStream будет дёргать метод writeByte. а это супер медленно. поэтому тебе нужен класс Stream. даже можешь писать сюда ради своего развлечния. ибо я устал. тол и ты упёрся в великий всепустой вакуум, то ли я настолько туп что действительно не понимаю какое отношение "плюс" и "функция" имеют АС3.
Старый 13.04.2011 23:51 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
*sigh* нет, ты не понял. Есть интерфейс, как элемент языка в ActionScript (например IDataOutput, IExternalizable etc), а есть интерфейс, как набор правил и возможностей для общения с другой программой (графический интерфейс, интерфейс командной строки и т.п.). Я говорю, про интерфейс к системным утилитам которые предназначены для записи / чтения из потоков. Мне не нужны сами по себе потоки, мне нужен интефейс доступа к системным утилитам, который бы позволил их более рациональное использование. И, нет, если бы такой интерфейс существовал, он бы не использовал флешевый writeByte для реализации writeBytes - потому, что это неоправданное ничем расточительство. На картинке выше ты видишь разницу между двумя программами, которые делают условно говоря одну и ту же операцию: пишут и читают из потока. Одна это делает на "более высоком" уровне, и занимает 100% процессорного времени, а другая делает это на "более низком" уровне и не занимет даже 1% процессорного времени.
Старый 14.04.2011 02:33 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
тебе удалось. поздравляю. ты от первоначальной темы удалился на столько на сколько можно, но никто так и не понял, чего ты хочешь, кроме вселенского добра. ощущение, что ты знаешь много букф, и поэтому складываешь их в слова. но кроме как "ты не понял" ничего не говоришь по делу. несёшь какую-то чушь неведомые интерфейсы, которые нафиг никому не нужны. хочешь стрим - нет, интерфейс - нет, конфетку - нет. ты скажи чего тебе надо на пальцах. не надо теологии. какие-то картинки не относящиеся к вопросу.
Цитата:
Сообщение от wvxvw
А то, что по логике, там должен был быть IDataInput - и я так пролетел пытаясь записать в сокет, который в функцию передавал как DataInput. Пришлось левый ByteArray добавлять, чтобы сначала в него прочитать, а потом уже в сокет.
к этой фразе твой бред никакого отношения не имеет. что бы доказать свою правоту ты придумал неведомую теорию о заговоре. прикрутил дотнет и чуть не самого всевышнего. я ничерта не понимаю.
 

 


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


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