Предлагаю следующий набор функций для чтения и записи в Blob-поля ("Поле объекта OLE" MS Access) сжатых ZLib файлов. Жду замечаний... (Имею маленький вопрос: обязательно ли использовать внутри процедуры Finalize()?).
unit NBlobZlib;
interface
uses Windows, KOL, ADODB_TLB, KolZlib;
function StreamZCompress(Dest, Source: PStream): DWord;
function StreamZDecompress(Dest, Source: PStream; Count: DWord): DWord;
function WriteFileToBlob(const aFileName: KolString): OleVariant;
function WriteBlobToFile(aField: Field; const aFileName: KolString): OleVariant;
type
TBlobByteData = array of Byte;
const
STRM_ERROR = DWord (-1);
implementation
function WriteFileToBlob(const aFileName: KolString): OleVariant;
var F, M: PStream; B: TBlobByteData;
begin
F:= NewReadFileStream(aFileName);
M:= NewMemoryStream;
try
StreamZCompress(M, F);
SetLength(B, M.Size);
Move(M.Memory^, B[0], M.Size);
Result:= B;
finally
Finalize(B);
F.Free;
M.Free;
end;
end;
function WriteBlobToFile(aField: Field; const aFileName: KolString): OleVariant;
var Buf: Pointer; M, F: PStream;
begin
Result:= Null;
F:= NewWriteFileStream(aFileName);
M:= NewMemoryStream;
try
Result:= AField.Value;
Buf:= VarArrayLock(Result);
M.Write(buf^, aField.ActualSize);
StreamZDecompress(F, M, 0);
finally
VarArrayUnlock(Result);
F.Free;
M.Free;
end;
end;
function StreamZDecompress(Dest, Source: PStream; Count: DWord): DWord;
var Zipper: PStream;
Size: DWord;
begin
try
Source.Seek(0, spBegin);
if Source.Read (Size, 4) <> 4 then Exit;
if not NewZLibDStream (Zipper, Source, nil) then Exit;
Result:= Stream2Stream(Dest, Zipper, Size);
finally
if Zipper <> nil then Zipper.Free;
end;
end;
function StreamZCompress(Dest, Source: PStream): DWord;
var Zipper: PStream; Size: DWord;
begin
Size:=Source.Size;
Source.Seek(0, spBegin);
Dest.Write (Size, 4);
try
If not NewZLibCStream (Zipper, clMax, Dest, nil) then Exit;
Result:= Stream2Stream(Zipper, Source, Size);
finally
if Zipper <> nil then Zipper.Free;
end;
end;