2017-08-16 32 views
0

我修改被写入在Delphi 6.0保存的数据被破坏;长度> = 100KB

我在Oracle中的表与名为FILE_CONTENT BLOB列的程序。

我已经成功上传了大约100 KB的XML文件。我已验证文件内容是否使用SQL Developer正确上传。

我遇到的问题是当我尝试将文件内容从数据库下载回文件。这是我使用donwload它的一个示例代码:

procedure TfrmDownload.Save(); 
var 
    fileStream: TFileStream; 
    bField: TBlobField; 
begin 
    dmDigital.qrGetData.Open; 
    dmDigital.RequestLive := True; 
    bField := TBlobField(dmDigital.qrGetData.FieldByName('FILE_CONTENT')); 
    fileStream := TFileStream.Create('FILE.XML', fmCreate); 
    bField.SaveToStream(fileStream); 
    FlushFileBuffers(fileStream.Handle); 
    fileStream.Free; 
    dmDigital.qrGetData.Close; 
end; 

上面的代码已下载文件的内容FILE.XML。我正在使用RequestLive:=True以便能够下载大BLOB(否则文件内容被截断为最大32K)

生成的文件与原始文件大小相同。但是,当我将下载的文件与原始文件进行比较时,会有一些差异(例如最后一个字符丢失,其他字符也会更改),因此下载内容时似乎存在问题。

你知道错在哪里吗?

该问题似乎与Delphi代码有关,因为我已经尝试使用C#并且文件内容已正确下载。

+0

你为什么打电话FlushFileBuffers –

+0

我现在知道,它不会有所作为,如果我把它与否,但起初似乎该文件被截断(至少是最后一个字符)......这就是为什么我尝试flushfilebuffers –

+0

这不是一个好主意。去掉它。 –

回答

0

不要使用TBlobField.SaveToStream()直接使用TDataSet.CreateBlobStream(),而不是(这是什么TBlobField.SaveToStream()内部使用反正):

procedure TfrmDownload.Save; 
var 
    fileStream: TFileStream; 
    bField: TField; 
    bStream: TStream; 
begin 
    dmDigital.qrGetData.Open; 
    try 
    dmDigital.RequestLive := True; 
    bField := dmDigital.qrGetData.FieldByName('FILE_CONTENT'); 
    bStream := bField.DataSet.CreateBlobStream(bField, bmRead); 
    try 
     fileStream := TFileStream.Create('FILE.XML', fmCreate); 
     try 
     fileStream.CopyFrom(bStream, 0); 
     FlushFileBuffers(fileStream.Handle); 
     finally 
     fileStream.Free; 
     end; 
    finally 
     bStream.Free; 
    end; 
    finally 
    dmDigital.qrGetData.Close; 
    end; 
end; 

TDataSet.CreateBlobStream()允许DataSet决定访问BLOB数据的最佳方式。如果返回的TStream未能正确传递数据,那么使用的TStream类实现中断,或底层数据库驱动程序有问题。尝试采取CopyFrom()的方程,所以你可以验证数据,因为它正在检索:

procedure TfrmDownload.Save; 
const 
    MaxBufSize = $F000; 
var 
    Buffer: array of Byte; 
    N: Integer; 
    fileStream: TFileStream; 
    bField: TField; 
    bStream: TStream; 
begin 
    dmDigital.qrGetData.Open; 
    try 
    dmDigital.RequestLive := True; 
    bField := dmDigital.qrGetData.FieldByName('FILE_CONTENT'); 
    bStream := bField.DataSet.CreateBlobStream(bField, bmRead); 
    try 
     fileStream := TFileStream.Create('FILE.XML', fmCreate); 
     try 
     //fileStream.CopyFrom(bStream, 0); 
     SetLength(Buffer, MaxBufSize); 
     repeat 
      N := bStream.Read(PByte(Buffer)^, MaxBufSize); 
      if N < 1 then Break; 
      // verify data here... 
      fileStream.WriteBuffer(PByte(Buffer)^, N); 
     until False; 
     FlushFileBuffers(fileStream.Handle); 
     finally 
     fileStream.Free; 
     end; 
    finally 
     bStream.Free; 
    end; 
    finally 
    dmDigital.qrGetData.Close; 
    end; 
end;