Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Проблема при распаковке файла GZipом


Автор: Hinidu 12.12.2009, 13:59
Мне нужно взять архивный файл из изолированного хранилища и распаковать его по указанному пути. Но при распаковке относительно больших файлов(например маленькие 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();

Запаковывался файл подобным образом. Помогите, пожалуйста, понять в чем проблема! Заранее очень благодарен.

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

Автор: Hinidu 13.12.2009, 18:47
PashaPash, спасибо большое, теперь буду знать.

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

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

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

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

Автор: Heinzz 14.12.2009, 21:39
проблема такая у NetworkStream, если читать пока нечего он и не предупредит гад smile а заполнит нулями.
http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/31057b8c-3300-4b71-9e87-9f17ec0be06a

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

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

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

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

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

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

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

Автор: PashaPash 15.12.2009, 20:43
Цитата(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 - это зачерпнуть из ведра ровно полную кружку. Или меньше, если вдруг совсем перестанет капать - закроется сокет. Если в ведре недостаточно воды - подождать пока накапает.

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

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

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

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

Автор: Heinzz 17.12.2009, 11:16
спасибо, будем пробывать

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)