Profrager

Advanced Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Bulat_Ziganshin кажется нашел по какой причине возникают глюки с внешним фильтром.. Юзаю WinAPI функции ReadFile и WriteFile (думаю и в сишных прогах весь ввод/вывод в конечном итоге работает через них). копипаст с msdn Код: BOOL WINAPI ReadFile( __in HANDLE hFile, __out LPVOID lpBuffer, __in DWORD nNumberOfBytesToRead, __out_opt LPDWORD lpNumberOfBytesRead, __inout_opt LPOVERLAPPED lpOverlapped ); | тут в nNumberOfBytesToRead указываем сколько хотим читать байт, а по адресу в lpNumberOfBytesRead сохраняется сколько реально было прочитано. Так вот, когда hFile является обычным файлом, то функция читает ровно столько, сколько указали в nNumberOfBytesToRead, кроме случаев когда встретился конец файла. Соответственно в lpNumberOfBytesRead всегда возвращается указанное на входе число байт (кроме оговоренного случая). Тут все хорошо, можно по этому параметру фиксировать конец потока или ошибку чтения. НО! Если hFile указывает на stdin, то в функция может читать меньшее число байт, чем указано во входном параметре, поэтому рассчитывать уже нельзя, что функция прочитает нужное нам число байт. И как показали опыты, чем быстрее была обработка предыдущих считанных байт, тем меньше он сможет в следующий раз считать. Так же заметил факт, что обычно считывается количество байт являющееся степенью двойки (131072, 262144 байт и т.д.). Выходом явилось написание функции, контролирующей чтение: Код: function MyReadFile (File1:THandle;mybufer:pointer;readedSize:cardinal;var RealReadedSize:cardinal):boolean; var tmpReadedSize,myRealReadedSize:cardinal; begin result:=ReadFile(File1,mybufer^,readedSize,myRealReadedSize,nil) and (myRealReadedSize<>0); tmpReadedSize:=readedSize; RealReadedSize:=myRealReadedSize; while (myRealReadedSize<tmpReadedSize) and result do begin inc (cardinal(mybufer),myRealReadedSize); dec(tmpReadedSize,myRealReadedSize); result:=ReadFile(File1,mybufer^,tmpReadedSize,myRealReadedSize,nil) and (myRealReadedSize<>0); inc (RealReadedSize,myRealReadedSize); end; end; | т.е. после того как ReadFile возвратила меньшее число байт, чем мы задали, то пытаемся считать еще раз остаток. У меня все заработало при замене этой функцией все ReadFile во своем внешнем фильтре. Не знаю как выполнена программно в си функция чтения fread, но возможно строки srep'а, типа Код: len = file_read (fstat, buf, statsize1); len += file_read (fin, buf+statsize1, compsize1-statsize1); if (len!=compsize1) error (ERROR_COMPRESSION, "Decompression problem: unexpected end of input file or I/O error"); | у кого-то и вызывают ошибки CRC при работе совместно с фриарком из-за указанной мной особенности работы ReadFile (хотя может fread это сама фиксит, а ошибки возникают по каким-то другим причинам, которые мне не удалось определить).
| Всего записей: 888 | Зарегистр. 22-05-2010 | Отправлено: 22:28 20-04-2011 | Исправлено: Profrager, 22:30 20-04-2011 |
|