TF1Book
3 отговора
134 прегледа
TF1Book
Задавам въпроса отново, защото никой не ми отговори.
Някой знае ли как се използват методите ReadFromBlob и WriteToBlob на TF1Book. Необходими ми са за четене и запис от и в база.
Сорса е следния:
Query.Open;
Stream := TMemoryStream.Create;
TBlobField(Query.FieldByName('BLOB_FIELD')).SaveToStream(Stream);
F1Book1.ReadFromBlob(Cardinal(Stream.Memory), 0);
Дава грешка: 'Invalid file'
Някой знае ли как се използват методите ReadFromBlob и WriteToBlob на TF1Book. Необходими ми са за четене и запис от и в база.
Сорса е следния:
Query.Open;
Stream := TMemoryStream.Create;
TBlobField(Query.FieldByName('BLOB_FIELD')).SaveToStream(Stream);
F1Book1.ReadFromBlob(Cardinal(Stream.Memory), 0);
Дава грешка: 'Invalid file'
Re: TF1Book
Пробвай това. Като ако искаш, сложи там където трябва try...finally.
Не ми се рови в документацията, това на теб го оставам, как да разбереш колко е голям блока от памет, който ще се записва. Имам идея, ама е малко "дървена".
var
BlobStream:TMemoryStream;
BlobSize, MyBlob:Cardinal;
pBlob:Pointer;
procedure TForm1.BtWriteClick(Sender: TObject);
begin
BlobSize:=20000;
F1Book1.SaveWindowInfo;
MyBlob := GlobalAlloc(GMEM_MOVEABLE, BlobSize);
F1Book1.WriteToBlob(MyBlob, 0);
pBlob := globalLock(MyBlob);
BlobStream:=TMemoryStream.Create;
BlobStream.Write(pBlob^,GlobalSize(myBlob));
BlobStream.Seek(0,0);
globalUnlock(MyBlob);
globalFree(myBlob);
end;
Изчистваш си целия F1Book1, и опитваш да прочетеш данните от паметта:
procedure TForm1.BtReadClick(Sender: TObject);
begin
BlobSize := BlobStream.Size;
MyBlob := GlobalAlloc(GMEM_MOVEABLE, BlobSize);
pBlob := globalLock(MyBlob);
BlobStream.Read(pBlob^, BlobSize);
F1Book1.ReadFromBlob(MyBlob, 0);
globalUnlock(MyBlob);
globalFree(myBlob);
BlobStream.Free;
end;
Хайде, и пиши при успех!
Не ми се рови в документацията, това на теб го оставам, как да разбереш колко е голям блока от памет, който ще се записва. Имам идея, ама е малко "дървена".
var
BlobStream:TMemoryStream;
BlobSize, MyBlob:Cardinal;
pBlob:Pointer;
procedure TForm1.BtWriteClick(Sender: TObject);
begin
BlobSize:=20000;
F1Book1.SaveWindowInfo;
MyBlob := GlobalAlloc(GMEM_MOVEABLE, BlobSize);
F1Book1.WriteToBlob(MyBlob, 0);
pBlob := globalLock(MyBlob);
BlobStream:=TMemoryStream.Create;
BlobStream.Write(pBlob^,GlobalSize(myBlob));
BlobStream.Seek(0,0);
globalUnlock(MyBlob);
globalFree(myBlob);
end;
Изчистваш си целия F1Book1, и опитваш да прочетеш данните от паметта:
procedure TForm1.BtReadClick(Sender: TObject);
begin
BlobSize := BlobStream.Size;
MyBlob := GlobalAlloc(GMEM_MOVEABLE, BlobSize);
pBlob := globalLock(MyBlob);
BlobStream.Read(pBlob^, BlobSize);
F1Book1.ReadFromBlob(MyBlob, 0);
globalUnlock(MyBlob);
globalFree(myBlob);
BlobStream.Free;
end;
Хайде, и пиши при успех!
Re: TF1Book
Благодаря за помоща на ИвКо. Тествах сорса и всичко работи. Но нещата се оказаха по- лесни.
Метода F1Book1.WriteToBlob сам прави GlobalAlloc. Достатъчно е да му се подаде променлива от
тип Cardinal. Не е необходима предварително заделяне на буфер, както и проблема с неговата
големина. Разбрах това случайно, като му подавах малки (дори 0) буфери, а всичко си работеше.
Пробвах дори и:
Procedure Test;
var
C: Cardinal;
begin
F1Book1.WriteToBlob(C, 0);
F1Book2.ReadFromBlob(C, 0)
end
ето крайния вариант:
var
Stream: TMemoryStream;
procedure TForm1.Button1Click(Sender: TObject);
var
C: Cardinal;
P: Pointer;
begin
F1Book1.WriteToBlob(C, 0);
Stream := TMemoryStream.Create;
P := GlobalLock(C);
Stream.SetSize(GlobalSize(C));
Stream.WriteBuffer(P^, GlobalSize(C));
GlobalUnlock(C);
GlobalFree(C)
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
F1Book2.ReadFromBlob(Cardinal(Stream.Memory), 0);
Stream.Free
end;
Друг начин е (като ИвКо):
procedure TForm1.Button2Click(Sender: TObject);
var
C: Cardinal;
P: Pointer;
begin
C := GlobalAlloc(GMEM_MOVEABLE, Stream.Size);
P := GlobalLock(C);
Stream.Position := 0;
Stream.ReadBuffer(P^, Stream.Size);
Stream.Free;
F1Book2.ReadFromBlob(C, 0);
GlobalUnlock(C);
GlobalFree(C)
end;
Метода F1Book1.WriteToBlob сам прави GlobalAlloc. Достатъчно е да му се подаде променлива от
тип Cardinal. Не е необходима предварително заделяне на буфер, както и проблема с неговата
големина. Разбрах това случайно, като му подавах малки (дори 0) буфери, а всичко си работеше.
Пробвах дори и:
Procedure Test;
var
C: Cardinal;
begin
F1Book1.WriteToBlob(C, 0);
F1Book2.ReadFromBlob(C, 0)
end
ето крайния вариант:
var
Stream: TMemoryStream;
procedure TForm1.Button1Click(Sender: TObject);
var
C: Cardinal;
P: Pointer;
begin
F1Book1.WriteToBlob(C, 0);
Stream := TMemoryStream.Create;
P := GlobalLock(C);
Stream.SetSize(GlobalSize(C));
Stream.WriteBuffer(P^, GlobalSize(C));
GlobalUnlock(C);
GlobalFree(C)
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
F1Book2.ReadFromBlob(Cardinal(Stream.Memory), 0);
Stream.Free
end;
Друг начин е (като ИвКо):
procedure TForm1.Button2Click(Sender: TObject);
var
C: Cardinal;
P: Pointer;
begin
C := GlobalAlloc(GMEM_MOVEABLE, Stream.Size);
P := GlobalLock(C);
Stream.Position := 0;
Stream.ReadBuffer(P^, Stream.Size);
Stream.Free;
F1Book2.ReadFromBlob(C, 0);
GlobalUnlock(C);
GlobalFree(C)
end;
Re: TF1Book
Идеално!!
Много се радвам. Между впрочем GlobalAlloc заделя само първоначален размер на буфера, и затова след това се използва GlobalSize за определяне на действително заетите байтчета... Но не бях толкова смел, като теб, за да пробвам и подам неинициализиран Handle към WriteToBlob... Сигурно защото съм вече остарял и не ставам за програмист
Ами... Успех с програмата!!!

Ами... Успех с програмата!!!