今天总算顺利通过了测试了,但是中间老师有问代码的具体作用,我又一个文件流和blob流的使用是参照了书上的例子,虽然大致的功能还是知道,但是有些细节部分还不是很清楚,后天答辩怕又问到这方面的问题,所以想请教一下高手,帮帮小妹吧!
   请高手将每一句的功能和作用帮忙解释清楚一下,越详细越好,还请帮忙执教一下,文件流和blob流到底是一个什么样的工作方法,在数据库中使用他们来存储文档,是不是将文档内容直接放到数据库中,还是储存的文档的其他信息。万分感谢了!!!
   代码如下:
1   procedure TForm4.BitBtn2Click(Sender: TObject);
var
  MemSize: Integer;
  Buffer: PChar;
  MyFile: TFileStream;
  Stream: TBlobStream;
begin
   MyFile:=TFileStream.Create('c:\temp.tmp',fmCreate);
    with query1 do
    begin
      Open;
      Stream:=TBlobStream.Create(FieldByName('文本') as TBlobField, bmRead);
      MemSize := Stream.Size;
      Inc(MemSize);
      Buffer := AllocMem(MemSize);
     try
        Stream.Read(Buffer^,MemSize);
        MyFile.Write(Buffer^,MemSize);
        statictext1.caption:='文件名:'+FieldByName('文件名').Asstring;
        statictext2.caption:='文件大小:'+FieldByName('文件大小').Asstring+'字节';
      finally
        MyFile.Free;
        Stream.Free;
      end;
    end;
      if FileExists('c:\temp.DOC') then
         DeleteFile('c:\temp.DOC');
      if FileExists('c:\temp.tmp') then
      begin
        RenameFile('c:\temp.tmp', 'c:\temp.DOC');
        Doc_ole.CreateObjectFromFile('c:\temp.DOC',False);
       Doc_ole.Run;
      end;
end;
2   procedure TForm4.BitBtn1Click(Sender: TObject);
var
  MemSize:Integer;
  Buffer:pChar;
  MyFile:TFileStream;
  Stream:TBlobStream;
  filename:string;
begin
  table1.insert;
  OpenDialog1.Filter:='WORD文档(*.DOC)|*.DOC';
  if OpenDialog1.Execute then
  begin
    filename:=OpenDialog1.FileName;
    MyFile:=TFileStream.Create(fileName,fmOpenRead);
    with table1 do
    begin
      Open;
      edit;
      Stream:=TBlobStream.Create(FieldByName('文本')as TBlobField,
       bmWrite);
      MemSize:=MyFile.Size;
      Inc(MemSize);
      Buffer:=AllocMem(MemSize);
      try
        Stream.Seek(0,soFromBeginning);
        MyFile.Read(Buffer^,MemSize);
        Stream.Write(Buffer^,MemSize);
    FieldByName('文件名').AsString:=ExtractFileName(fileName);
          FieldByName('文件大小').AsString:=inttostr(MemSize-1);
          statictext1.caption:='文件名:'+ExtractFileName(fileName);
          statictext2.caption:='文件大小:'+inttostr(Memsize-1)+'字节';
          finally
            MyFile.Free;
            Stream.Free;
          end;
            try
              table1.post;
              except
                showmessage('保存失败!');
                halt;
              end;
                showmessage('保存成功,正在加载文档!');
                Doc_Ole.CreateObjectFromFile(fileName,False);
                Doc_Ole.Run;
              end;
end;
end;

解决方案 »

  1.   

    其实要实现将存在数据库中的文件流取出来存为本地文件完全不用这么复杂(反过来也一样不用这么复杂),两个函数就可已搞定TBlobField.SaveToFile, TBlobField.LoadFromFile.
    用法大致如下:
    var bf: TBlobField;
    bf = table1.FieldByName('文本') as TBlobField;
    bf.SaveToFile('c:\temp.doc');
    **************************************
    bf = table1.FieldByName('文本') as TBlobField;
    bf.LoadFromFile('c:\temp.doc');
    table1.post;
    比你用流倒来倒去简单多了.
      

  2.   

    还有,如果你想知道文件的大小,TBlobField 也有相应的属性。看帮助吧。
      

  3.   

    数据库中使用blob流来存储文件(注意,不光是文档,所有类型文件都可以存进数据库,blob流对象是将文件以二进制形式读进,相应字段为image,在数据库里是以二进制数据形式存在,存入数据库的文件所以可以不管文件类型,所以一般还要将文件类型信息(主要是扩展名)也存进数据库。这样在将文件读出时可以存成相应类型文件//建立文件流,文件名为'c:\temp.tmp'此文件名即为数据库里的文件所应对应的文件名
    //其实主要是扩展名要和数据库里的文件类型一致,这样才能将存成的文件用相应的软件打开
    第一段程序的主要功能是将数据库里的对应大数据字段里的文件信息读出,并存成本地机上的一个文件
    第二段程序的主要功能就是将文件存进数据库MyFile:=TFileStream.Create('c:\temp.tmp',fmCreate);    with query1 do
        begin
          Open;     //建立数据库大数据对象流(一般是存储在数据库中的文件),对应字段为'文本',采用读方式,
     
        Stream:=TBlobStream.Create(FieldByName('文本') as TBlobField, bmRead);
      //分配内存      
          MemSize := Stream.Size;
          Inc(MemSize);
          Buffer := AllocMem(MemSize);
         try
       
    //将数据库大数据字段中的二进制位值读出,并读到缓冲区里     
            Stream.Read(Buffer^,MemSize);
    //将缓冲区里的信息写文件        
          MyFile.Write(Buffer^,MemSize);//设置界面相关信息        
    statictext1.caption:='文件名:'+FieldByName('文件名').Asstring;
            statictext2.caption:='文件大小:'+FieldByName('文件大小').Asstring+'字节';
          finally//析沟相关流对象        
            MyFile.Free;
            Stream.Free;
          end;
      

  4.   

    //建立数据库大数据对象的文件流,采用写方式,相应大数据字段为‘文本'
         Stream:=TBlobStream.Create(FieldByName('文本')as TBlobField,
           bmWrite);
    //获得文件大小信息
          MemSize:=MyFile.Size;
          Inc(MemSize);
    //分配缓冲区
          Buffer:=AllocMem(MemSize);
          try
    //大数据流从头开始写
            Stream.Seek(0,soFromBeginning);
    //读所有文件信息读进缓冲区(即文件的二进制信息)
            MyFile.Read(Buffer^,MemSize);
    //将缓冲区中的内容写入大数据流--本操作完成将数据存入数据库的操作
            Stream.Write(Buffer^,MemSize);
    //文件名信息进库
        FieldByName('文件名').AsString:=ExtractFileName(fileName);
    //文件大小信息进库          
    FieldByName('文件大小').AsString:=inttostr(MemSize-1);
              statictext1.caption:='文件名:'+ExtractFileName(fileName);
              statictext2.caption:='文件大小:'+inttostr(Memsize-1)+'字节';
              finally
                MyFile.Free;
                Stream.Free;
              end;
    //ok提交
     table1.post;
    题外话:你的这段代码确实麻烦了,blob字段本生就有相应的存文件和取文件操作,你的程序相当于是相应的VCL函数的代码实现
      

  5.   

    我并不是自己不想列,我现在基本上已经明白了功能,只是有些方法没用过,具体的东西不太了解而已阿!
       我现在还有几点不太明白的地方:
       1 buffer:PChar;   PChar是什么类型,为什么要将缓冲定义成这种类型
       2 inc(MemSize);   是什么意思,是将MemSize增一吗?
       3 buffer:=AllocMem(MemSize);     应该是分配缓冲大小,但是allocMem是什么方法
       4 FileByName('文件名').Asstring:=ExtractFileName(filename);  中间Asstring和ExtractFileName具体是什么方法
       5 halt   是什么方法
      

  6.   

    1,2,3,4,5
    看看Delphi的帮助就全知道了!
      

  7.   

    相信你的English不会比我还差。看帮助吧。
      

  8.   

    天啊,你连这些基本的东西都不知道,如果老师问,你肯定死菜。赶紧找一本pascal的书看看。
    PChar是一个指针,可以指向一个内存区域,但是对区域的数据操作的时候是按照Char模式操作的。他在很大的方面可以和string类型相互强制转换,类似c中的字符串。如果你想确切了解指针,建议你需要看看C的书关于指针的或者Pascal中关于指针的章节(现在Delphi书中很多连基础知识都不讲,真是恶心)。实在不行,你可以看汇编的书,了解内存到底是怎么回事情。
    allocMem是delphi的用法还是c的用法记不清楚了,或者是api的用法。你看帮助吧。
    关于第5个问题,天啊,你还是看看帮助吧。呵呵。不过Table的任意字段都可以使用AsString,AsInteger等进行转换。我真不知道你程序是怎么编出来的。
    有时间多看看基础的资料,都快毕业了,如果你不是搞计算机专业的还好,否则你肯定Over。