Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема при распаковке файла GZipом, При распаковке теряется часть информации 
V
    Опции темы
Hinidu
Дата 12.12.2009, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 5.12.2009
Где: Калининград

Репутация: нет
Всего: нет



Мне нужно взять архивный файл из изолированного хранилища и распаковать его по указанному пути. Но при распаковке относительно больших файлов(например маленькие txt распаковываются без проблем) теряется часть информации и файлы зачастую просто не открываются. При этом WinRAR распаковывает эти же файлы без проблем.
Код

IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForAssembly();
IsolatedStorageFileStream isolStream = new IsolatedStorageFileStream(sourceFile,
    FileMode.Open,
    isf);
GZipStream zipStream = new GZipStream(isolStream, CompressionMode.Decompress);
BinaryReader binReader = new BinaryReader(zipStream);

FileStream fs = File.Create(destinationFile);

isolStream.Position = 0;
while (isolStream.Position != isolStream.Length)
{
    byte[] myBytes = binReader.ReadBytes(1024);
    fs.Write(myBytes, 0, myBytes.Length);
}

binReader.Close();
fs.Flush();
fs.Close();

Запаковывался файл подобным образом. Помогите, пожалуйста, понять в чем проблема! Заранее очень благодарен.
PM MAIL ICQ   Вверх
PashaPash
Дата 12.12.2009, 23:12 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 9
Всего: 49



Hinidu, GZipStream и BinaryReader используют внутренние буфферы при работе с данными. Т.е. данные могут быть вычитаны из isolStream до соотв. вызова binReader.ReadBytes. Правильный признак что "байты закончились" - Position != Length на myBytes.Length > 0.


--------------------
PM MAIL WWW   Вверх
Hinidu
Дата 13.12.2009, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 5.12.2009
Где: Калининград

Репутация: нет
Всего: нет



PashaPash, спасибо большое, теперь буду знать.
PM MAIL ICQ   Вверх
Heinzz
Дата 13.12.2009, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 12.12.2008
Где: .net

Репутация: 3
Всего: 9



Цитата(PashaPash @ 12.12.2009,  23:12)
Hinidu, GZipStream и BinaryReader используют внутренние буфферы при работе с данными. Т.е. данные могут быть вычитаны из isolStream до соотв. вызова binReader.ReadBytes. Правильный признак что "байты закончились" - Position != Length на myBytes.Length > 0.

а как бороться с этим? Такая проблема есть и у других потоков.


--------------------
user posted image
PM MAIL   Вверх
PashaPash
Дата 14.12.2009, 01:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 9
Всего: 49



Цитата(Heinzz @  13.12.2009,  19:05 Найти цитируемый пост)
а как бороться с этим? Такая проблема есть и у других потоков. 

Какая проблема? И зачем бороться с буфферизацией?


--------------------
PM MAIL WWW   Вверх
Heinzz
Дата 14.12.2009, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 12.12.2008
Где: .net

Репутация: 3
Всего: 9



проблема такая у NetworkStream, если читать пока нечего он и не предупредит гад smile а заполнит нулями.
борьба с использованием своего буфера


--------------------
user posted image
PM MAIL   Вверх
PashaPash
Дата 15.12.2009, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 9
Всего: 49



Heinzz, по ссылке проблема вообще никак не связанная с внутренними буфферами. Никакими нулями NetworkStream ничего не заполняет.

Просто Stream.Read может прочитать меньше байт, чем у него попросили. Это явно сказано в документации, и это нормально поведение. А еще Stream.Read возвращает количество прочитаных байт. 
И еще, по той же ссылке - там достаточно было заменить BinaryReader.Read на BinaryReader.ReadBytes в ReadFromStream.


--------------------
PM MAIL WWW   Вверх
Heinzz
Дата 15.12.2009, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 12.12.2008
Где: .net

Репутация: 3
Всего: 9



Цитата(PashaPash @  15.12.2009,  00:03 Найти цитируемый пост)
там достаточно было заменить BinaryReader.Read на BinaryReader.ReadBytes в ReadFromStream. 

а если байт еще не пришел, а мы уже его таким образом начали читать? 

Цитата(PashaPash @  15.12.2009,  00:03 Найти цитируемый пост)
А еще Stream.Read возвращает количество прочитаных байт. 

это как раз int возвращаемое методом?

а он отличает 0 от null?


--------------------
user posted image
PM MAIL   Вверх
PashaPash
Дата 15.12.2009, 20:43 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 9
Всего: 49



Цитата(Heinzz @  15.12.2009,  19:30 Найти цитируемый пост)

а если байт еще не пришел, а мы уже его таким образом начали читать? 


Read (Stream.Read и BinaryReader.Read) вычитывает все "пришедшие" на данный момент байты. Возвращает количество прочитанных. Если байт "не пришел" - оно его не вычитывает.

ReadBytes читает count байт. Если "байт не пришел" - то ReadBytes тупо сидит и ждет пока байт придет. 

Цитата(Heinzz @  15.12.2009,  19:30 Найти цитируемый пост)

а он отличает 0 от null? 

да нет там никаких нулей, никаких null, и никакого чтения непришедших байт.

Представь что есть ведро с водой, в него капает тонкой струйкой. Это NetworkStream.
Read - это зачерпнуть из него кружкой (буффером) "сколько накапало" - зачерпывает то что уже есть в ведре, но не больше кружки.
ReadBytes - это зачерпнуть из ведра ровно полную кружку. Или меньше, если вдруг совсем перестанет капать - закроется сокет. Если в ведре недостаточно воды - подождать пока накапает.


Это сообщение отредактировал(а) PashaPash - 15.12.2009, 20:44


--------------------
PM MAIL WWW   Вверх
Heinzz
Дата 15.12.2009, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 12.12.2008
Где: .net

Репутация: 3
Всего: 9



Цитата(PashaPash @  15.12.2009,  20:43 Найти цитируемый пост)
Представь что есть ведро с водой, в него капает тонкой струйкой. Это NetworkStream.
Read - это зачерпнуть из него кружкой (буффером) "сколько накапало" - зачерпывает то что уже есть в ведре, но не больше кружки.
ReadBytes - это зачерпнуть из ведра ровно полную кружку. Или меньше, если вдруг совсем перестанет капать - закроется сокет. Если в ведре недостаточно воды - подождать пока накапает.

так нету в NetworkStream метода ReadBytes, только Read и ReadByte  smile 


--------------------
user posted image
PM MAIL   Вверх
PashaPash
Дата 16.12.2009, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 9
Всего: 49



Цитата(Heinzz @  15.12.2009,  22:28 Найти цитируемый пост)
так нету в NetworkStream метода ReadBytes, только Read и ReadByte    

так есть BinaryReader, с конструктром BinaryReader(Stream). и есть BinaryReader.ReadBytes. Товарищ по ссылке юзает BinaryReader, но вызывает BinaryReader.Read, получая странные результаты.


--------------------
PM MAIL WWW   Вверх
Heinzz
Дата 17.12.2009, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 12.12.2008
Где: .net

Репутация: 3
Всего: 9



спасибо, будем пробывать


--------------------
user posted image
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0495 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.