如何把文件以流的形式写入数据库? 如何把文件以流的形式写入数据库?数据库的字段类型应该是什么?还有就是如何把数据库的数据恢复为文件?各位大哥帮帮忙,无限感激!最好能给些代码。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 以下是一个用流保存与读取RichEdit的示例,你可以改一下,其实都是差不多的:存:var MemStrm:TMemoryStream;begin MemStrm:=TMemoryStream.Create; try RichEdit1.Lines.SaveToStream(MemStrm); Table1.Edit; TBlobField(Table1.FieldByName('RichEdit')).LoadFromStream(MemStrm); Table1.Post; finally MemStrm.Free; end;end;取:var MemStrm:TMemoryStream;begin MemStrm:=TMemoryStream.Create; try TBlobField(Table1.FieldByName('RichEdit')).SaveToStream(MemStrm); RichEdit1.Lines.LoadFromStream(MemStrm); finally MemStrm.Free; end;end; 楼上说的对,或者用TBlobStream对象来实现,方法和上面差不多的,请查看帮助 TMemoryStream的继承关系如下TObject|TStream|TCustomMemoryStream|TMemoryStream如何使用TMemoryStream?其实TmemoryStream使用就跟TStream 一样具体的属性,方法可看帮助。下举一例:如我想在内存中直接读写一个Bitmap,怎么办?TmemoryStream帮了你大忙var BitmapMemoryStream:TMemoryStream; Bitmap1:TBitmap;procedure TForm.Button1Click(Sender:TObject);begin BitmapmemroyStream:=TmemoryStream.Create; file://建立MemoryStream Bitmap1:=TBitmap.Create; try Bitmap1.LoadFromFile(’d:\Bitmap1.bmp’); except ShowMessage(’Error On LoadFile bitmap1.bmp’);end;end;procedure TForm.Button2Click(Sneder:Tobject);begin if Assigned(Bitmap1) then Bitmap1.SaveToStream(BitmapmemoryStream);end;procedure TForm.Button3Click(Sender:TObject);begin if BitmapMemoryStream<>nil then begin try BitmapMemroyStream.SaveToFile(’Bitmap1.str’); file://内存流保存,大小与 file://Bitmap1.bmp一样 except showmessage(’error on access memory!’); end; end;end;procedure TForm.Button4Click(Sender:TObject);var Buffer:Array[0..53] of char;begin if Assigned( BitmapMemroyStream) thentry BitmapMemroyStream.Seek(0,soFromBeginning); BitmapMemoryStream.Read(Buffer,54); if Buffer[0]=’B’ and Buffer[1]=’M’ then file://改写内存内容 begin BitmapMemoryStream.Seek(0,soFromBeginning); BitmapmemoryStream.Write(’ICE’,3); Button3Click(Sender);//将改写的内容写入文件 end;except ShowMessage(’error On Access memroyStream’);end;end;大家可看到用TMemoryStream对与内存读写多么方便,当然其实用不着先建一Bitmap可以用LoadFromFile直接引导文件,但是如果对于其它的内存流却是可以用上述方法上文只是抛转引玉,其它的一些功能大家可以看帮助,自己琢磨!还有很多其它的流式对象,大致都差不多,一通百通!如何将一个流的内容写入到剪贴板中,并处理这个技巧是参考Delphi的剪贴板类的实现来完成的。将一个流的内容放入剪贴板,首先要注册你自已的格式,使用RegisterClipboardFormat()函数然后做下面三步:1.创建一个内容流,并将内容写进去2.创建一个全局的内容区,并将流的内容写入3.调用ClipBoard.SetAsHandle()将内容写入剪贴板将内容写入剪贴板中varhbuf : THandle;bufptr : Pointer;mstream : TMemoryStream;beginmstream := TMemoryStream.Create;try{-- 处理流的代码 --}hbuf := GlobalAlloc(GMEM_MOVEABLE, mstream.size);trybufptr := GlobalLock(hbuf);tryMove(mstream.Memory^, bufptr^, mstream.size);Clipboard.SetAsHandle(CF_MYFORMAT, hbuf);finallyGlobalUnlock(hbuf);end;exceptGlobalFree(hbuf);raise;end;finallymstream.Free;end;end;请注意不要将分配的全局缓冲区释放,这个工作由剪贴板来完成,在读出数据中你应该将它复制后处理。将剪贴板内容读出来varhbuf : THandle;bufptr : Pointer;mstream : TMemoryStream;beginhbuf := Clipboard.GetAsHandle(CF_MYFORMAT);if hbuf <> 0 then beginbufptr := GlobalLock(hbuf);if bufptr <> nil then begintrymstream := TMemoryStream.Create;trymstream.WriteBuffer(bufptr^, GlobalSize(hbuf));mstream.Position := 0;{-- 处理流的代码 --}finallymstream.Free;end;finallyGlobalUnlock(hbuf);end;end;end;end;在Dephi中使用TStream读写数据的技巧在Dephi中提供了一个抽象的数据类型TStream来支持对流式数据的操作。这些数据通常来自文件、数据库、内存对象、OLE对象等,TStream提供了统一、简洁的方法来进行数据的读写。在通常情况下,我们并不需要直接使用TStream类,对流式数据的读写封装在VCL控件的方法中。但是如果这些方法无法满足我们的要求,就需要自己手动控制数据的读写。一、 TStream的常用的方法和属性:---- 1. function Read(var Buffer; Count: Longint): Longint; virtual; abstract---- 2. function Write(const Buffer; Count: Longint): Longint; virtual; abstract;---- 3. function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract;---- 4. property Position: Longint;---- 5. property Size: Longint---- Read,Write,Seek都是纯虚函数,提供了数据读写和定位的抽象的方法。Read方法将数据从Stream中读到Buffer缓冲区中,Write则实现相反的操作,返回值表示实际读写数据的大小。Seek提供了在Stream中移动数据指针的方法。参数Origin可以取soFromBeginning,soFromCurrent,soFromEnd 三个值,Offset是偏移量,返回值是当前Stream数据指针的位置。---- Position表示了数据指针在Stream中的位置。这个属性是可读写的,它实际上就是通过调用Seek方法实现的,所以实际使用时使用这个属性更为方便一些。Size属性表示当前Stream的大小,对于不同的Stream,有些时候是只读的。二、 Stream数据的读写。---- 1. SaveToStream(Stream: TStream ); file://将类中的数据写到Stream的当前位置中---- 2. LoadFromStream(Stream: TStream); file://从当前位置读入Stream里的数据---- 实际使用时我们基本上只要使用上面两个函数就可以了。三、 例子---- TStream的继承树图如图1所示(略),实际使用时比较常用的是TFileStream,TMemoryStream,TblobStream,就以这三种流举一例说明具体用法。---- 创建一个窗体Form1,放置三个按钮btnRead,btnInvert,btnSave和一个文件打开对话框OpenDialog1以及数据控件DataSource1,Table1,test.---- 使用Dephi提供的Database Desktop创建一个表test,表里有一个字段域Image,数据库文件名存为test.db。在窗体上放置一个TDatabase控件dbTest,一个TTable控件Table1,一个DataSource控件DataSource1,一个TDBNavigator控件DBNavigator1。将dbTest与刚才Desktop创建的数据库相连,Table1的TableName属性设为test.db,DataSource1的DataSet属性设为Table1,DBNavigator1的DataSource属性设为DataSource1,VisibleButtons属性前四个设为TRUE。此外,将dbtest的Connected设为TRUE,Table1的Active属性设为TRUE,使得数据库一开始就处于打开状态。---- 事件代码编写如下:---- 1. btnRead的Click事件,这里演示了TFileStream的用法。varMS: TFileStream;begin if OpenDialog1.Execute then begin MS:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead); Image1.Picture.Bitmap.LoadFromStream(MS); MS.Free; end;end;---- 2. btnInvert的Click事件,这里演示了TMemoryStream的用法。其中使用了Invert函数,这是一个简单的将图象反色的函数(仅对真彩图象有效),它返回一个指向处理过的图象数据块的指针。var MS: TMemoryStream; pImage: pointer;begin MS:=TMemoryStream.create; Image1.Picture.Bitmap.SaveToStream(MS); MS.Position:=0; pImage:=Invert(MS.Memory, MS.size); file://Memory属性是指向实际内存块的指针 MS.Write(pImage^,MS.size); MS.Position:=0; file://上一行代码使指针移到了Stream末尾,所以要复位 Image1.Picture.Bitmap.LoadFromStream(MS); FreeMem(pImage); MS.Free;end;Invert函数如下:function TForm1.Invert(pImage: pointer; size: Integer): pointer;var pData, pMem: PChar; i: Integer;begin pMem:=AllocMem(Size);//分配 CopyMemory(pMem,pImage,size); pData:=pMem+54; for I:=0 to Size-54-1 do begin pData^:=Char(not integer(pData^));//地址取反 pData:=pData+1; end; Result:=pMem;end;---- 1. btnSave的Click事件,这里演示了TMemoryStream的另一种用法,将Stream中的数据写到数据库中去。var MS: TMemoryStream;begin MS:=TMemoryStream.create; Image1.Picture.Bitmap.SaveToStream(MS); MS.Position:=0; Table1.Append; file://在数据库中添加一条记录 TBlobField(Table1.FieldbyName('image')).LoadFromStream(MS); Table1.Post; file://将所作的更新写入数据库end;---- 4. DBNavigator1的Click事件,这里演示了TBlobStream的用法,使用了和写入时不同的方法来读出数据库的图象数据。var MS: TStream;begin With Table1 do MS:=CreateBlobStream(FieldbyName(’image’),bmRead); Image1.Picture.Bitmap.LoadFromStream(MS); MS.Free;end; 非常感谢 xzhifei(飞) 、 snake_eye(天使的披风) 的提示。问题已经解决。为了共同学习,我把我的方法也说一说,虽然这是一个很菜鸟的问题。我要打开不同格式的多种文件,比如,图片、word文档、Excel文档还有其它并且要把这些不同的文档在同一个窗口里打开,并一起存入数据库。我首先说说我的打开方式:在这里我用了ActiveX控件RichTextBox,并通过OLE.procedure TfrmContractOther.cmdInsertClick(Sender: TObject);var nCount:Integer; sname:string; strFileName:String;begin nCount := RichTextBox1.OLEObjects.Count; sname := 'f'+inttostr(nCount); if OpenDialog1.Execute() then begin strFileName := OpenDialog1.FileName; RichTextBox1.OLEObjects.Add(nCount, sname ,strFileName,0); end;end;把不同的文档在RichTextBox1中打开后,接下来的问题就是如何来存入数据库了。导入数据库的方法可以用流的形式来实现,但是RichTextBox1支持savefile()和loadfile()方法,所以实现起来就简单得多了。实现方法: 1、保存:先将RichTextBox中的对象保存为文件——>将文件保存到数据库——>删除文件 2、打开:将数据库中的对象还原到一个文件对象中——>RichTextBox装入文件以上是我的做法,问题很简单耽误大家时间了。很希望大家在解决一个问题的时候,能够说说自己的心得。谢谢楼上的三位大哥。 有谁玩QQ跑胡子的 关于数据表的合并问题? 问个菜问题,如何制作“保存到文件夹”的那个对话筐? COM+高手进 打印问题,非常急 为什么quickreport在面板里看不到,而要自己去装呢? 如何查找指定的数据 推荐一个学delphi的好软件,delphi学习宝典,下载地址: 下载区下的TEXCELL怎么用?网上dephi编的勤工助学管理系统密码是什么? 我的检讨书 delphi代码编写器左边有个树形东西,列出了代码中全部东西 进销存中客户的应收应付怎么计算,是每月结转吗?需要专门建表吗?(只要是合理建议保证给分)
存:
var
MemStrm:TMemoryStream;
begin
MemStrm:=TMemoryStream.Create;
try
RichEdit1.Lines.SaveToStream(MemStrm);
Table1.Edit;
TBlobField(Table1.FieldByName('RichEdit')).LoadFromStream(MemStrm);
Table1.Post;
finally
MemStrm.Free;
end;end;
取:
var
MemStrm:TMemoryStream;
begin
MemStrm:=TMemoryStream.Create;
try
TBlobField(Table1.FieldByName('RichEdit')).SaveToStream(MemStrm);
RichEdit1.Lines.LoadFromStream(MemStrm);
finally
MemStrm.Free;
end;
end;
TObject
|
TStream
|
TCustomMemoryStream
|
TMemoryStream
如何使用TMemoryStream?
其实TmemoryStream使用就跟TStream 一样
具体的属性,方法可看帮助。
下举一例:
如我想在内存中直接读写一个Bitmap,怎么办?
TmemoryStream帮了你大忙var
BitmapMemoryStream:TMemoryStream;
Bitmap1:TBitmap;procedure TForm.Button1Click(Sender:TObject);
begin
BitmapmemroyStream:=TmemoryStream.Create; file://建立MemoryStream
Bitmap1:=TBitmap.Create;
try
Bitmap1.LoadFromFile(’d:\Bitmap1.bmp’);
except
ShowMessage(’Error On LoadFile bitmap1.bmp’);
end;
end;procedure TForm.Button2Click(Sneder:Tobject);
begin
if Assigned(Bitmap1) then
Bitmap1.SaveToStream(BitmapmemoryStream);
end;procedure TForm.Button3Click(Sender:TObject);
begin
if BitmapMemoryStream<>nil then
begin
try
BitmapMemroyStream.SaveToFile(’Bitmap1.str’); file://内存流保存,大小与
file://Bitmap1.bmp一样
except
showmessage(’error on access memory!’);
end;
end;
end;procedure TForm.Button4Click(Sender:TObject);
var
Buffer:Array[0..53] of char;
begin
if Assigned( BitmapMemroyStream) then
try
BitmapMemroyStream.Seek(0,soFromBeginning);
BitmapMemoryStream.Read(Buffer,54);
if Buffer[0]=’B’ and Buffer[1]=’M’ then file://改写内存内容
begin
BitmapMemoryStream.Seek(0,soFromBeginning);
BitmapmemoryStream.Write(’ICE’,3);
Button3Click(Sender);//将改写的内容写入文件
end;
except
ShowMessage(’error On Access memroyStream’);
end;
end;大家可看到用TMemoryStream对与内存读写多么方便,当然其实用不着先建一Bitmap
可以用LoadFromFile直接引导文件,但是如果对于其它的内存流却是可以用上述方法
上文只是抛转引玉,其它的一些功能大家可以看帮助,自己琢磨!
还有很多其它的流式对象,大致都差不多,一通百通!
如何将一个流的内容写入到剪贴板中,并处理这个技巧是参考Delphi的剪贴板类的实现来完成的。将一个流的内容放入剪贴板,
首先要注册你自已的格式,使用RegisterClipboardFormat()函数
然后做下面三步:
1.创建一个内容流,并将内容写进去
2.创建一个全局的内容区,并将流的内容写入
3.调用ClipBoard.SetAsHandle()将内容写入剪贴板
将内容写入剪贴板中
var
hbuf : THandle;
bufptr : Pointer;
mstream : TMemoryStream;
begin
mstream := TMemoryStream.Create;
try
{-- 处理流的代码 --}
hbuf := GlobalAlloc(GMEM_MOVEABLE, mstream.size);
try
bufptr := GlobalLock(hbuf);
try
Move(mstream.Memory^, bufptr^, mstream.size);
Clipboard.SetAsHandle(CF_MYFORMAT, hbuf);
finally
GlobalUnlock(hbuf);
end;
except
GlobalFree(hbuf);
raise;
end;
finally
mstream.Free;
end;
end;
请注意不要将分配的全局缓冲区释放,这个工作由剪贴板来完成,在读出数据中
你应该将它复制后处理。将剪贴板内容读出来
var
hbuf : THandle;
bufptr : Pointer;
mstream : TMemoryStream;
begin
hbuf := Clipboard.GetAsHandle(CF_MYFORMAT);
if hbuf <> 0 then begin
bufptr := GlobalLock(hbuf);
if bufptr <> nil then begin
try
mstream := TMemoryStream.Create;
try
mstream.WriteBuffer(bufptr^, GlobalSize(hbuf));
mstream.Position := 0;
{-- 处理流的代码 --}
finally
mstream.Free;
end;
finally
GlobalUnlock(hbuf);
end;
end;
end;
end;
在Dephi中使用TStream读写数据的技巧在Dephi中提供了一个抽象的数据类型TStream来支持对流式数据的操作。这些数据通常来自文件、
数据库、内存对象、OLE对象等,TStream提供了统一、简洁的方法来进行数据的读写。
在通常情况下,我们并不需要直接使用TStream类,对流式数据的读写封装在VCL控件的方法中。
但是如果这些方法无法满足我们的要求,就需要自己手动控制数据的读写。一、 TStream的常用的方法和属性:
---- 1. function Read(var Buffer; Count: Longint): Longint; virtual; abstract
---- 2. function Write(const Buffer; Count: Longint): Longint; virtual; abstract;---- 3. function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract;---- 4. property Position: Longint;---- 5. property Size: Longint---- Read,Write,Seek都是纯虚函数,提供了数据读写和定位的抽象的方法。
Read方法将数据从Stream中读到Buffer缓冲区中,Write则实现相反的操作,
返回值表示实际读写数据的大小。Seek提供了在Stream中移动数据指针的方法。
参数Origin可以取soFromBeginning,soFromCurrent,soFromEnd 三个值,
Offset是偏移量,返回值是当前Stream数据指针的位置。---- Position表示了数据指针在Stream中的位置。这个属性是可读写的,
它实际上就是通过调用Seek方法实现的,所以实际使用时使用这个属性更为方便一些。
Size属性表示当前Stream的大小,对于不同的Stream,有些时候是只读的。二、 Stream数据的读写。
---- 1. SaveToStream(Stream: TStream ); file://将类中的数据写到Stream的当前位置中
---- 2. LoadFromStream(Stream: TStream); file://从当前位置读入Stream里的数据---- 实际使用时我们基本上只要使用上面两个函数就可以了。三、 例子
---- TStream的继承树图如图1所示(略),实际使用时比较常用的是TFileStream
,TMemoryStream,TblobStream,就以这三种流举一例说明具体用法。
---- 创建一个窗体Form1,放置三个按钮btnRead,btnInvert,
btnSave和一个文件打开对话框OpenDialog1以及数据控件DataSource1,Table1,test.---- 使用Dephi提供的Database Desktop创建一个表test,表里有一个字段域Image,数据库文件名存为test.db。
在窗体上放置一个TDatabase控件dbTest,一个TTable控件Table1,一个DataSource控件DataSource1,
一个TDBNavigator控件DBNavigator1。将dbTest与刚才Desktop创建的数据库相连,Table1的TableName属性设为test.db,
DataSource1的DataSet属性设为Table1,DBNavigator1的DataSource属性设为DataSource1,VisibleButtons属性前四个设为TRUE。
此外,将dbtest的Connected设为TRUE,Table1的Active属性设为TRUE,使得数据库一开始就处于打开状态。---- 事件代码编写如下:---- 1. btnRead的Click事件,这里演示了TFileStream的用法。var
MS: TFileStream;
begin
if OpenDialog1.Execute then
begin
MS:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
Image1.Picture.Bitmap.LoadFromStream(MS);
MS.Free;
end;
end;---- 2. btnInvert的Click事件,这里演示了TMemoryStream的用法
。其中使用了Invert函数,这是一个简单的将图象反色的函数(仅对真彩图象有效),
它返回一个指向处理过的图象数据块的指针。
var
MS: TMemoryStream;
pImage: pointer;
begin
MS:=TMemoryStream.create;
Image1.Picture.Bitmap.SaveToStream(MS);
MS.Position:=0;
pImage:=Invert(MS.Memory, MS.size); file://Memory属性是指向实际内存块的指针
MS.Write(pImage^,MS.size);
MS.Position:=0; file://上一行代码使指针移到了Stream末尾,所以要复位
Image1.Picture.Bitmap.LoadFromStream(MS);
FreeMem(pImage);
MS.Free;
end;Invert函数如下:
function TForm1.Invert
(pImage: pointer; size: Integer): pointer;
var
pData, pMem: PChar;
i: Integer;
begin
pMem:=AllocMem(Size);//分配
CopyMemory(pMem,pImage,size);
pData:=pMem+54;
for I:=0 to Size-54-1 do
begin
pData^:=Char(not integer(pData^));//地址取反
pData:=pData+1;
end;
Result:=pMem;
end;---- 1. btnSave的Click事件,这里演示了TMemoryStream的另一种用法,
将Stream中的数据写到数据库中去。
var
MS: TMemoryStream;
begin
MS:=TMemoryStream.create;
Image1.Picture.Bitmap.SaveToStream(MS);
MS.Position:=0;
Table1.Append; file://在数据库中添加一条记录
TBlobField(Table1.FieldbyName('image')).LoadFromStream(MS);
Table1.Post;
file://将所作的更新写入数据库
end;---- 4. DBNavigator1的Click事件,这里演示了TBlobStream的用法,
使用了和写入时不同的方法来读出数据库的图象数据。
var
MS: TStream;
begin
With Table1 do
MS:=CreateBlobStream(FieldbyName(’image’),bmRead);
Image1.Picture.Bitmap.LoadFromStream(MS);
MS.Free;
end;
并且要把这些不同的文档在同一个窗口里打开,并一起存入数据库。我首先说说我的打开方式:
在这里我用了ActiveX控件RichTextBox,并通过OLE.
procedure TfrmContractOther.cmdInsertClick(Sender: TObject);
var
nCount:Integer;
sname:string;
strFileName:String;
begin
nCount := RichTextBox1.OLEObjects.Count;
sname := 'f'+inttostr(nCount);
if OpenDialog1.Execute() then
begin
strFileName := OpenDialog1.FileName;
RichTextBox1.OLEObjects.Add(nCount, sname ,strFileName,0);
end;
end;把不同的文档在RichTextBox1中打开后,接下来的问题就是如何来存入数据库了。
导入数据库的方法可以用流的形式来实现,但是RichTextBox1支持savefile()
和loadfile()方法,所以实现起来就简单得多了。
实现方法:
1、保存:先将RichTextBox中的对象保存为文件——>将文件保存到数据库——>删除文件
2、打开:将数据库中的对象还原到一个文件对象中——>RichTextBox装入文件
以上是我的做法,问题很简单耽误大家时间了。
很希望大家在解决一个问题的时候,能够说说自己的心得。谢谢楼上的三位大哥。