2017-08-16 41 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;