TF1Book

3 отговора 134 прегледа
#1

TF1Book

Задавам въпроса отново, защото никой не ми отговори.
Някой знае ли как се използват методите ReadFromBlob и WriteToBlob на TF1Book. Необходими ми са за четене и запис от и в база.
Сорса е следния:

Query.Open;
Stream := TMemoryStream.Create;
TBlobField(Query.FieldByName('BLOB_FIELD')).SaveToStream(Stream);
F1Book1.ReadFromBlob(Cardinal(Stream.Memory), 0);

Дава грешка: 'Invalid file'

Отговор
в отговор на Питaщ #2

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;

Хайде, и пиши при успех!

Отговор
в отговор на ИвKo #3

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;

Отговор
в отговор на Питaщ #4

Re: TF1Book

Идеално!! Много се радвам. Между впрочем GlobalAlloc заделя само първоначален размер на буфера, и затова след това се използва GlobalSize за определяне на действително заетите байтчета... Но не бях толкова смел, като теб, за да пробвам и подам неинициализиран Handle към WriteToBlob... Сигурно защото съм вече остарял и не ставам за програмист
Ами... Успех с програмата!!!

Отговор