0

I have problems retrieving a blob field containing images, then saving it to file.
The downloaded file does not seem to be in the correct format; if I open it with a hex editor it contains the word @R_BLOB@

What could be wrong?

bg: = TAdsBlobStream.Create (adsQuery1.FieldByName ('PAGE') as TBlobField, bmReadWrite);
f: = TMemoryStream.create;
bg.Position: = 0;
f.CopyFrom (bg, bg.size);
f.SaveToFile ('c: \ tmp \ db \ img \' + IntToStr (n) + '. jpg');
f.free;

Thanks

Jan Doggen
  • 8,799
  • 13
  • 70
  • 144
slucarini
  • 41
  • 1
  • 3
  • Try `f := TFileStream.Create('c:\tmp\db\img\000.jpg', fmOpenWrite); try f.Seek(0, soFromBeginning); f.CopyFrom(bg, 0); finally f.free; end;` http://www.freepascal.org/docs-html/rtl/classes/tfilestream.create.html There is little reson to make intermediate RAM buffer for that. – Arioch 'The Jun 21 '13 at 08:46
  • 1
    Well, actually that is still redundant. Why not do direct `bg.SavetoFile('c:\tmp\db\img\000.jpg');` ? – Arioch 'The Jun 21 '13 at 08:47
  • 2
    if you would read http://www.sybase.com/files/White_Papers/SY-Advantage-Delphi-Getting-Started-Guide-080409-WP.pdf you would also find `(adsQuery1.FieldByName ('PAGE') as TBlobField).SavetoFile('c:\tmp\db\img\000.jpg');` – Arioch 'The Jun 21 '13 at 08:50
  • 1
    Did you ruled out that the blob data really contain that mark, that it is just how it was written to database ? run some native to Advantage db editor and try to export the blob from it, maybe it was stred into DB that way originally ? – Arioch 'The Jun 21 '13 at 08:51

2 Answers2

2

I just used the following code to write a small (9K) JPEG into an ADS BLOB Field via an ADSTable, read it back into an ADSBlobStream and write it to disk in a separate location, and all worked fine. The new copy of the image opens fine in Windows Picture Viewer, and I don't see any extraneous characters in it with a hex viewer.

// Code to create the test table, done in ARC32
CREATE TABLE Test (ID Integer, Pic BLOB);

Dropped a TADSSettings, TADSQuery, and two plain TButton components on a new blank VCL form. Here are the button OnClick handlers (obviously the filenames in both handlers are hard-coded and should be replaced by actual filenames on your machine):

procedure TForm1.Button1Click(Sender: TObject);
var
  Blob: TAdsBlobStream;
  Strm: TFileStream;
  Tbl: TAdsTable;
begin
  Tbl := TAdsTable .Create(nil);
  try
    Tbl.DatabaseName := AdsQuery1.DatabaseName;
    Tbl.TableType := ttAdsCDX;
    Tbl.TableName := 'Test.dbf';
    Tbl.Open;
    Tbl.Edit;
    Blob := Tbl.CreateBlobStream(AdsQuery1.Fields[1], bmWrite) as TAdsBlobStream;
    try
      Strm := TFileStream.Create('E:\Test\Images\Big folder.jpg', fmOpenRead);
      try
        Blob.CopyFrom(Strm, Strm.Size);
      finally
        Strm.Free;
      end;
    finally
      Blob.Free;
    end;
  finally
    Tbl.Post;
    Tbl.Close;
    Tbl.Free;
    AdsQuery1.Open;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Blob: TAdsBlobStream;
  Strm: TFileStream;
begin
  AdsQuery1.SQL.Text := 'SELECT ID, pic FROM test';
  AdsQuery1.Open;
  Blob := AdsQuery1.CreateBlobStream(AdsQuery1.Fields[1], bmRead) as TAdsBlobStream;
  try
    Strm := TFileStream.Create('E:\TempFiles\BigFolder.jpg', fmCreate);
    try
      Strm.CopyFrom(Blob, Blob.Size);
    finally
      Strm.Free;
    end;
  finally
    Blob.Free;
  end;
end;

Run the app, and click Button1 to insert the image into the Test table. Then click Button2 to read it back out and write it to a new file on disk.

Ken White
  • 123,280
  • 14
  • 225
  • 444
0

The initial text @R_BLOB@ depended on the type of table set in the properties TableType of the component TadsQuery, setting it to ttAdsCDX, export work.

Thanks all.

slucarini
  • 41
  • 1
  • 3