2014-12-27 51 views
0

我正在處理一個小字節修補程序,但遇到了一個錯誤。複製文件在fmOpenReadWriteMode中打開時失敗

修改之前複製文件失敗,沒有錯誤,(沒有看到複製的輸出),但文件修補程序成功。

這裏是補丁代碼

procedure DoMyPatch(); 
var 

    i: integer; 
    FileName: string; 
    input: TFileStream; 

    FileByteArray, ExtractedByteArray: array of Byte; 

begin 
    FileName := 'Cute1.res'; 

    try 
    input := TFileStream.Create(FileName, fmOpenReadWrite); 
    except 
    begin 
     ShowMessage('Error Opening file'); 
     Exit; 
    end 
    end; 

    input.Position := 0; 
    SetLength(FileByteArray, input.size); 
    input.Read(FileByteArray[0], Length(FileByteArray)); 

    for i := 0 to Length(FileByteArray) do 
    begin 
    SetLength(ExtractedByteArray, Length(OriginalByte)); 
    ExtractedByteArray := Copy(FileByteArray, i, Length(OriginalByte)); 

// function that compares my array of bytes 
    if CompareByteArrays(ExtractedByteArray, OriginalByte) = True then 
    begin 
     // Begin Patching 

    CopyFile(PChar(FileName), PChar(ChangeFileExt(FileName, '.BAK')), 
      true); =======>>> fails at this point, no copied output is seen. 

     input.Seek(i, SoFromBeginning); 


      input.Write(BytetoWrite[0], Length(BytetoWrite)); =====>>> patches successfully 

      input.Free; 
     ShowMessage('Patch Success'); 
     Exit; 
    end; 

    end; 
    if Assigned(input) then 
    begin 
    input.Free; 
    end; 

    ShowMessage('Patch Failed'); 


end; 

旁註:它複製的罰款,如果我試圖複製之前關閉文件流。順便說一下,我已經在Delphi 7和XE7上測試過了。 謝謝

回答

3

您無法複製該文件,因爲您在爲文件流打開文件時專門鎖定了文件,這就是爲什麼CopyFile失敗。

在嘗試呼叫CopyFile之前,您應該關閉該文件。這會要求你重新打開文件來修補它。或者也許用不同的共享模式打開文件。

一些其他意見:

  • 的異常處理不好實現。不要在這裏發現異常。讓他們上升到最高水平。
  • 生命週期管理鬆動。你可以很容易地泄漏。你需要了解try/finally
  • 您溢出緩衝區。動態數組的有效索引爲0Length(arr)-1(含)。或者使用low()high()
  • 您不檢查由CopyFile返回的值。打電話給Win32Check
  • Copy函數返回一個新的數組。所以你做了一個虛假的電話SetLength。要複製整個陣列,請使用Copy的一個參數超載。
  • 在此函數中顯示消息可能是一個錯誤。更好地讓來電者提供用戶反饋。

代碼中還有許多其他的怪物,我已經耗盡精力將它們全部指出來。我想我得到了主要的。

+0

感謝您的回覆。 你能解釋一下更多的例子還是這兩個例子,特別是第二個例子。 異常處理執行不當。 生命週期管理鬆動。你可以很容易地泄漏。 – 2014-12-27 18:08:22

+1

你不應該捕捉任何例外。讓更高層的呼叫堆做到這一點。用try/finally保護對象。這已經很好地覆蓋了。我的最高投票答案之一是全面的報道。 – 2014-12-27 18:11:12

+2

這些其他奇怪之一是'如果分配(輸入)然後input.Free;'。這是分配的雙重檢查,因爲這是'TObject.Free'的主要工作:如果分配調用析構函數 – 2014-12-28 10:10:54

相關問題