200分求助: 客户端Blob字断的读写问题? (200分)

  • 主题发起人 主题发起人 Frank
  • 开始时间 开始时间
F

Frank

Unregistered / Unconfirmed
GUEST, unregistred user!
问题:

在服务器端数据库中的Blob字段内存放DB格式的文件,
如何直接在客户端的DBgrid将Blob字段内的DB显示出来,或将Blob字段的DB存放在客户
端,然后再使用.

多谢!
 
将Blob存成文件在访问
 
文件不大的话
可以考虑采用流的方式将数据读出来
读到本机
在显示
可以吗?
 
Delphi数据库应用程序开发中图像数据的存取技术

  Delphi提供了数据访问(DataAccess)和数据控制(
DataControls)的可视化控件,能够方便快捷地产生具有
良好界面且功能强大的数据库应用程序。对于涉及图像数
据(含Graphic字段)的数据库应用程序,如人事管理信
息系统等,图像数据的存取技术是一个关键。然而,有关D
elphi下图象的存取,特别是图像的保存方面的技术各种
资料上很少提及。下面,笔者结合一个简单的例子来说明


   一、图像数据的保存

  1.创建一个含有Graphic字段的数据库列表。

  在WindowsISQ(或Databasedesktop)下createdatab
asemydb.gdb

  createtablemyfrieds

  (namevarchar(15)notnull,telephonevarchar(
12),addressvarchar(30),zipvarchar(8),pictu
revarchar(15),imageblob);

  其中,picture字段用于保存图像的名称(包括路径
),image(Graphic字符)则用于存储图像,其数据类型
为“blob”。

  2.建立窗体(如图1所示),设置窗体中各控件的属
性。

  该窗体的主要功能是将某人信息进行编辑和保存。需
要注意的图像保存所用的图像框必须用TImage而不能用TD
BIm?age,编辑框宜用Tedit而不宜用TDBEdit,这一点与
图像的读取恰好相反。

  其中,各主要控件的属性设置如下:

  Datasource1.Dataset:Κtable1;

  Table1.Databasename:Κmydb.gdb;

  Table1.Tablename:Κmyfriends;

  Table1.active:Κtrue;

  其他诸如Caption之类的属性设置不再叙述。

  3.数据处理程序的建立。

  (1)图像( .bmp文件)打开的处理。

  procedureTForm1.pictopenbtnClick(Sender:TOb
ject);

  beginopendialog1.execute;

  image1.picture.loadfromfile

  (opendialog1.filename);

  end;

  (2)图像保存的处理。

  图像保存的处理程序完成把在窗体1所编辑的信息包
括图像保存到相应的数据库中,其关键是要定义一个Graph
ic类型的变量且该变量要用assing()函数传递到相应数
据库中保存。具体程序如下:

  procedureTform1.Savebtnclick(sender:TObject
);

  vargraphic1:TGraphic;

  begingraphic1:ΚTGraphic.Create;

  graphic1.loadfromfile(opendialog1.filename
);

  table1.insert;

  table1.fieldbyname(′name′).asstring:Κe
dit1.text;

  table1.fieldbyname(′telephon′).asstring
:Κedit2.text;

  table1.fieldbyname(′address′).asfloat:
Κ(edit3.text);

  table1.fieldbyname(′zip′).asfloat:Κ(e
dit4.text);

  table1.fields[4].assign(graphic1);

  table1.post;

  graphic1.free;

  end;

   二、图像数据的读取

  在数据库数据(包括Graphic字段的数据)的读取和
浏览方面,Delphi这一具有强大代码自动生成功能的面向
对象的开发工具的优越性得到淋漓尽致的体现。毫不夸张
地说,不需要一条语句即可完成这一功能!

  建立窗体(如下图所示),设置各控件的属性。

  图中Table1和Datasource1的属性的设置与数据的保
存部分(图1)相同,所不同的是数据库数据的读取时用TD
BEdit和TD?BImage控件而不用TEdit和TImage。控件TDBE
dit和TDBImage只要将datafield属性设置为其相对应的域
;TDBNavigator的datasouce属性设置为datasource1即可

 
seucag:

可以给我一个例子吗?

多谢!
 
用assign也可以啊!
 

  随着数据库及多媒体技术的发展,人们需要存储、处理的信息的种类越来越多。数据库中存储的数据不再只是文本、数字,而且还可能是图形、声音、视频等等,各式各样的类型。早期的数据库是无法处理这些类型的数据的。现在的数据库中为处理这些特殊格式的数据,设置了一种大二分对象(BLOB-Binary Large OBject)。
  BLOB在数据库的表中实际上是以二进制数据的形式存放的。由于BLOB的特殊性,一般的程序都无法处理它。比如,如果在一张表中存在BLOB,当用Dattabase Desktop(Delphi在带的数据库管理工具)打开它时,BLOB列将只显示BLOB字样。至于该列中实际存的是什么数据是单靠Database DeskTop是无法得到的。如果在我们编制的程序中,用DBGrid控件打开一个有BLOB字段的表,效果也一样。我们的程序无法直接显示、编辑以及插入BLOB字段。可见,常规的方法是不能满足要求的。
  如何处理BLOB字段,可以借鉴一些可视的桌面数据库的方法。如Access中,BLOB字段是可以通过双击该字段的方式打开。Access是通过OLE的方式实现BLOB数据的编辑及处理的,所以我们也可以在通过程序中设置OLE控件的方法来处理BLOB。下面,我们先讨论操作BLOB的关键问题,然后给出一个简单的例子。

操作BLOB的关键
要在程序中自如地操作BLOB数据,无非是解决以下几个问题:
1. BLOB数据的入库操作
2. BLOB数据的显示
3. BLOB数据的编辑、修改
  由于数据的类型可能千变万化,所以,采用OLE方式是较方便的选择。我们可以在程序中放置一个OLE控件,用于显示、编辑各种BLOB数据。那么,问题的关键就是BLOB数据如何入库,以及数据库如何与OLE控件之间传递数据。

第一种解决方案是在库中直接保存原始数据。具体方法如下:
  BLOB数据的入库:要把BLOB数据入库,不能向普通的数据那样直接赋值;而是利用BLOB字段的LoadFromfile方法。采用这个方法,可以直接将各种数据的数据文件存入数据库。代码如下:
AblobField.LoadFromfile(aFileName);
  数据库与OLE控件间的数据传递也要通过数据文件。即,BLOB字段先将数据存盘;然后,OLE从将数据文件中创建所需要的OLE对象。代码如下:
AblobField.SaveToFile(aFileName);
AOleContainer.CreateObjectFromFile(aFileName);
注意:OLE对象不能直接使用LoadFromFile方法,因为,数据库中存放的BLOB对象的格式是文件原来的格式,而不是OLE格式,是不能直接读取的。直接读取将导致运行错误。

   第二种方案是在库中以OLE格式保存数据。具体方法如下:
  本方案的不同之处,在于数据入库前先进行格式的转换。格式的转换是通过OLE控件完成的。即,先创建OLE对象,然后入库。示例代码如下:
AOleContainer.CreateObjectFromFile(aFileName);
AoleContainer.SaveToFile(tmpFileName);
AblobField.LoadFromfile(tmpFileName);
  这样作的好处是,由于库中直接存储的是OLE格式,所以,在库与OLE控件之间的数据传递将非常方便。在这种情况下,可以通过文件直接传递:数据字段先将数据存到一个临时文件中,然后,OLE控件从临时文件中读取。即:
AblobField.SaveToFile(aFileName);
AOleContainer.LoadFromFile(aFileName);
另外,还可以通过内存流来完成。使用内存流,可减少磁盘操作,大大提高运行效率。即:
AblobField.SaveToStream(aStream);
AOleContainer.LoadFromStream(aStream);


下面是一个简单的例子。

一个简单的例子
  本例中,采用Paradox数据库。库中有两个字段,一个是字符型,另一个是BLOB型。我们在主Form上放一个OLE控件用于编辑及转换数据。一个Table控件操作数据库。源代码如下:
unit blob01;
interface
uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, Grids, DBGrids, Db, DBCtrls, OleCtnrs, DBTables, ExtCtrls;
type
 TForm1 = class(TForm)
  Panel1: TPanel;
  Panel2: TPanel;
  Splitter1: TSplitter;
  Panel3: TPanel;
  Table1: TTable;
  OleContainer1: TOleContainer;
  DBNavigator1: TDBNavigator;
  DataSource1: TDataSource;
  DBGrid1: TDBGrid;
  OpenBtn: TButton;
  CloseBtn: TButton;
  OpenDialog1: TOpenDialog;
  LoadBtn: TButton;
  Table1Filename: TStringField;
  Table1ABlob: TBlobField;
  procedure OpenBtnClick(Sender: TObject);
  procedure CloseBtnClick(Sender: TObject);
  procedure LoadBtnClick(Sender: TObject);
  procedure Table1AfterScroll(DataSet: TDataSet);
private
 { Private declarations }
public
 { Public declarations }
end;
var
 Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.OpenBtnClick(Sender: TObject);
begin
  Table1.Open; //打开数据库
end;

procedure TForm1.CloseBtnClick(Sender: TObject);
begin
  Table1.Close; //关闭数据库
end;

//打开一个数据文件、创建OLE对象、将对象数据存入数据库
procedure TForm1.LoadBtnClick(Sender: TObject);
var
fn: string;
begin
 if OpenDialog1.Execute then begin //打开文件
  fn := ExtractFileName(OpenDialog1.FileName);
  Table1FileName.AsString := fn;
  OleContainer1.CreateObjectFromFile(OpenDialog1.FileName, False); //创建OLE对象
  OleContainer1.SaveToFile("tmp"); //将OLE数据存入临时文件
  Table1ABlob.LoadFromFile("tmp"); //将OLE数据存入数据库
 end;
end;

//定义此方法用于显示当前记录中的OLE对象
procedure TForm1.Table1AfterScroll(DataSet: TDataSet);
begin
 if not Table1ABlob.IsNull then begin
  Table1ABlob.SaveToFile("tmp"); //数据存入临时文件
  OleContainer1.LoadFromFile("tmp"); //从临时文件中读取OLE对象
 end;
end;

end.


该程序在Delphi 5.0下编译通过。
 
你可以使用DbCtrlGrid控件
它能实现你想要的功能,同时显示多条记录(包括BLOB 字段)
 
可以将文件以BLOB存入数据库,使用时再从库中读出BLOB生成文件使用.
从文件存入数据库
QUERY.PARAMBYNAME('字段').LOADFROMFILE('文件名',FTBLOB);
从库中读出存入文件
TBLOBFIELD((QUERY.FIELDBYNAME('字段')).SAVETOFILE('文件名'');

DBGRID
 
用临时文件最简单,不然就自己create内存表,rxlib里有
 
我基本解决我所面对的问题,

谢谢各位的帮助!
 
后退
顶部