![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Есть ли CRC в TDecompressionStream? [D7, WinXP]
начинающий © (2004-08-03 15:42:00)Как узнать, поврежден ли файл, который создан при помощи TCompressionStream?
Digitman (2004-08-05 08:18:00) [1]
> начинающий (04.08.04 23:44) [16]
да, пардон ..
писал навскидку, упустил этот важный момент
действительно, первым в файле должен идти Int64 (для передачи 2-м параметром в decompressstream.CopyFrom), отражающий размер упакованных данных, а следом - собственно упакованные данные
одним словом, загляни в каталог
(%Delphi%)\Demos\Midas\Intrcpt
там есть наглядный пример использования интересующих тебя классов
начинающий (2004-08-04 23:44:00) [2]к Digitman ©
Как понимать Ваше:outStream.CopyFrom(unZip); //распаковываем - здесь возможны исключения, связанные с повреждением
Ведь надо:
function CopyFrom(Source: TStream; Count: Int64): Int64;
Или 0 вместо второго параметра, чтобы считать всё. Но откуда Зип знает, когда наступит всё?
Вы сами пробовали читать из TDecompressionStream при помощи CopyFrom? Я пробовал, и когда указывал ноль - выскакивало исключение. Так что размер несжатого файла всё равно придётся куда-то впихивать.
Поправьте меня, если я не прав.
Digitman (2004-08-04 13:04:00) [3]
> Sergey_Masloff (04.08.04 12:51) [14]
это было более для наглядности
Sergey_Masloff (2004-08-04 12:51:00) [4]Digitman © (04.08.04 11:31) [11]
>XMLDocument.XML.Text := StrPas(PChar(outStream.Memory)); //готово
StrPas на фиг не нужен тут. Это атавизм ;-)
А так все верно.
WondeRu (2004-08-04 11:43:00) [5]муть зеленая! Пользуй для сжатия и декомпрессии следующие функции из Mastering Delphi 7:
procedure CompressStream (aSource, aTarget: TStream);
var
comprStream: TCompressionStream;
begin
comprStream := TCompressionStream.Create(
clFastest, aTarget);
try
comprStream.CopyFrom(aSource, aSource.Size);
comprStream.CompressionRate;
finally
comprStream.Free;
end;
end;
procedure DecompressStream (aSource, aTarget: TStream) ;
var
decompStream: TDecompressionStream;
nRead: Integer;
Buffer: array [0..1023] of Char;
begin
decompStream := TDecompressionStream.Create(aSource);
try
// aStreamDest.CopyFrom (decompStream, size) doesn't work
// properly as you don't know the size in advance,
// so I've used a similar "manual" code
repeat
nRead := decompStream.Read(Buffer, 1024);
aTarget.Write (Buffer, nRead);
until nRead = 0;
finally
decompStream.Free;
end;
end;
вообще скачай ZlibEx: www.dellapasqua.com! ZlibEx лишен глюков и быстрее! В стандарте в Делфе Zlib версия 1.04, а в ZlibEx 1.2.1!
Digitman (2004-08-04 11:33:00) [6]
> "чистые" XML-данные
+ нуль-терминатор на конце (если использовать StrPas)
Digitman (2004-08-04 11:31:00) [7]
> начинающий (03.08.04 20:52) [8]
для простоты операторы обработки исключений и конструкторы/диструкторы вспом.объектов опущены
предполагаем , что в сжатом потоке нет ничего лишнего - "чистые" XML-данные
var
inStream, outStream :TMemoryStream;
..
inStream.LoadFromFile(FileName); //грузим сжатые данные из файла
..
UnCryptStream(inStream,Key); //расшифровываем
unZip := TDecompressionStream.Create(inStream);
outStream.CopyFrom(unZip); //распаковываем - здесь возможны исключения, связанные с повреждением
..
XMLDocument.XML.Text := StrPas(PChar(outStream.Memory)); //готово
начинающий (2004-08-04 11:12:00) [8]Именно так: в архиве содержится нечто вроде:
<Len><not Len><0..Len-1>
А Len и LenCopy - обычные переменные типа Integer.
И что Вас здесь так сильно смутило?
Sergey Masloff (2004-08-03 21:14:00) [9]Что-то ты не то делаешь
Читаешь 4 байта в буфер - это ты длину исходной строки записал туда изначально?
А потом читаешь в другой буфер следующие 4 байта?
И что потом с ними делается?
if Len<>(not LenCopy) then
начинающий (2004-08-03 20:52:00) [10]Код, возможно (даже скорее всего) не блещет чистотой стиля - уж не ругайте строго - делаю лишь первые шаги!
begin
inStream := TMemoryStream.Create;
try
try
inStream.LoadFromFile(FileName);
except
raise EXTReadError.Create
end;
UnCryptStream(inStream,Key);
unZip := TDecompressionStream.Create(inStream);
try
try
unZip.Read(Len,SizeOf(Integer));
//-Когда добавил это - вроди бы ошибки стихли---------
unZip.Read(LenCopy,SizeOf(Integer));
if Len<>(not LenCopy) then
raise EXTContentsDamaged.Create;
//----------------------------------------------------
GetMem(XMLData,Len+1);
XMLData[Len] := Chr(0);
unZip.Read(XMLData^,Len);
XMLDocument.Active := FALSE;
XMLDocument.XML.Text := XMLData;
XMLDocument.Active := TRUE;
finally
unZip.Free;
FreeMem(XMLData)
end
except
raise EXTContentsDamaged.Create
end
finally
inStream.Free
end
end
Sergey Masloff (2004-08-03 20:19:00) [11]начинающий (03.08.04 18:30) [6]
>Я хоть и начинающий, но такие вещи знаю :)
Это радует. Но в то что в случае сохранения целостности стека ты не попадаешь в обработчик except верить отказываюсь. Давай в студию тестовый код который это вызовет.
начинающий (2004-08-03 18:30:00) [12]Я хоть и начинающий, но такие вещи знаю :) В IDE отключены исключения, и запускаю я программу из Windows Commander 5.0. Единственной причиной появления Access violation я могу считать лишь то, что, возможно, TDecompressStream не всегда может определить, что поток "запорот". Ведь если это было бы не так, значит в архиве присутствует большая избыточность.
Sergey_Masloff (2004-08-03 17:40:00) [13]начинающий (03.08.04 17:28) [4]
>Может и исключение, но при этом управление в except не >переходит.
Ты, мил человек, не из среды ли программу запускаешь когда эти самые иногдаслучаются? Потому что если исключение в except не приходит то... Стек чтоли рушится? Врядли такой глюк в zlib пропустили
начинающий (2004-08-03 17:28:00) [14]Может и исключение, но при этом управление в except не переходит.
Digitman (2004-08-03 17:17:00) [15]
> произошёл Access violation
а это, по-твоему, не исключение ?
начинающий (2004-08-03 17:14:00) [16]Как раз именно так я и делал, но иногда случается такое, что до исключения дело даже не доходит: вылетает окошко с сообщением, что произошёл Access violation.
Digitman (2004-08-03 16:47:00) [17]загрузить его содержимое в TDecompressionStream и попытаться декомпрессировать ... возникшее исключение укажет на факт нарушения структуры сжатых данных