2014-01-24 48 views
1

當我嘗試檢查一個zip文件的有效性時,會引發該進程無法訪問該文件的異常,因爲該文件正在被另一個進程使用,但Open1.Click中的代碼打開zip文件沒有問題。 Valid1Click有什麼問題嗎?檢查Zip文件的有效性

procedure TForm1.Valid1Click(Sender: TObject); 
{ Is the zip file valid. } 
var 
    iZipFile: TZipFile; 
    iZipFilename: string; 
    iValid: Boolean; 
begin 
    Screen.Cursor := crHourGlass; 
    try 
    { Create the TZipFile Class } 
    iZipFile := TZipFile.Create; 
    try 
     if FileExists(ZipFilename1.Text) then 
     begin 
     iZipFilename := ZipFilename1.Text; 
     { Open zip file for reading } 
     iZipFile.Open(iZipFilename, zmRead); 
     iValid := iZipFile.IsValid(iZipFilename); 
     if iValid then 
      MessageBox(0, 'The zip file is valid.', 'Check Zip File', 
      MB_ICONINFORMATION or MB_OK) 
     else 
      MessageBox(0, 'The zip file is NOT valid.', 'Check Zip File', 
       MB_ICONWARNING or MB_OK); 
     end 
     else 
      begin 
       MessageBox(0, 'The zip file does not exist.', 'Warning', 
       MB_ICONWARNING or MB_OK); 
      end; 
     { Close the zip file } 
     iZipFile.Close; 
     finally 
     iZipFile.Free; 
     end; 
    finally 
     Screen.Cursor := crDefault; 
    end; 
end; 

procedure TForm1.Open1Click(Sender: TObject); 
{ Open zip file. } 
var 
    i: integer; 
    iZipFile: TZipFile; 
    iFilename: string; 
    iDateTime: TDateTime; 
    iCompressedSize: cardinal; 
    iUnCompressedSize: cardinal; 
    iCRC32: cardinal; 
    iCompressionMethod: word; 
    iFileComment: string; 
    iListItem: TlistItem; 
begin 
    if OpenDialog1.Execute then 
    begin 
    if FileExists(OpenDialog1.FileName) then 
    begin 
     iZipFile := TZipFile.Create; 
     try 
     ListView1.Items.Clear; 
     ZipFilename1.Text := OpenDialog1.FileName; 
     try 
      iZipFile.Open(ZipFilename1.Text, zmReadWrite); 
      for i := 0 to iZipFile.FileCount - 1 do 
      begin 
      iFilename := iZipFile.FileNames[i]; 
      iListItem := ListView1.Items.Add; 
      iListItem.Caption := iFilename; 
      iDateTime := FileDateToDateTime 
       (iZipFile.FileInfo[i].ModifiedDateTime); 
      iListItem.SubItems.Add(DateTimeToStr(iDateTime)); { 0 } 
      iCompressedSize := iZipFile.FileInfo[i].CompressedSize; 
      iListItem.SubItems.Add(FormatByteSize(iCompressedSize)); { 1 } 
      iUnCompressedSize := iZipFile.FileInfo[i].UncompressedSize; 
      iListItem.SubItems.Add(FormatByteSize(iUnCompressedSize)); { 2 } 
      iCRC32 := iZipFile.FileInfo[i].CRC32; 
      iListItem.SubItems.Add(IntToStr(iCRC32)); { 3 } 
      iCompressionMethod := iZipFile.FileInfo[i].CompressionMethod; 
      iListItem.SubItems.Add 
       (ZipCompressionToStr(iCompressionMethod)); { 4 } 
      iFileComment := iZipFile.Comment; 
      iListItem.SubItems.Add(iFileComment); { 5 } 
      end; 
      iZipFile.Close; 
     except 
      on E: Exception do 
      begin 
      ShowMessage(E.ClassName + #10#13 + E.Message); 
      end; 
     end; 
     finally 
     iZipFile.Free; 
     end; 
    end; 
    end; 

回答

3

你有這些行南轅北轍:

iZipFile.Open(iZipFilename, zmRead); 
iValid := iZipFile.IsValid(iZipFilename); 

第一行鎖定該文件,因此第二線失敗。致電Open之前,您必須致電IsValid

說了這麼多,因爲你使用zmRead,它應該調用IsValid再次打開該文件,因爲調用Open使用fmOpenRead是可能的。所以我懷疑在您使用的Delphi版本中可能存在ZIP文件代碼或文件流代碼中的錯誤。同樣,撥打IsValid之前Open一定能正常工作。

實際上,IsValid是一個類方法。你應該這樣稱呼它:

iValid := TZipFile.IsValid(iZipFilename); 

談到在年底同樣的事情,但它明確該方法調用不依賴於一個實例的狀態代碼的閱讀器。

事實上,我個人會乾脆打電話給IsValid,直接撥打Open。如果失敗了,我相信會提出一個有意義的錯誤信息。


更新

看起來你不想打開該文件在所有,只是要檢查它的有效性。在這種情況下,你不需要一個實例,你不需要調用構造函數,而只需要使用一個對TZipFile.IsValid的調用。

procedure TForm1.Valid1Click(Sender: TObject); 
begin 
    Screen.Cursor := crHourGlass; 
    try 
    if FileExists(ZipFilename1.Text) then 
    begin 
     if TZipFile.IsValid(ZipFilename1.Text) then 
     ... 
    finally 
    Screen.Cursor := crDefault; 
    end; 
end; 
+1

它開始看起來像開放甚至沒有需要在所有甚至可能是iZipFile:= TZipFile.Create;? – Bill

+0

啊,我以爲你想讀這個文件。如果你只想檢查有效性,那麼你根本不需要實例。 –

0

當大衛赫弗南初始計量:應該可以TZipFile ::打開(文件名,模式)後使用的isValid,因爲人們所期望的打開只讀文件不會阻止它給別人看的。

當使用基於文件名的開放式方法(另一個存在用於從TFileStream的讀f)中,它在內部創建FileStream,而它確實指定fmOpenRead,它設置共享模式打開這個流。

見本博客文章爲例關於如何可以先創建在其中指定的共享模式明確一個TFileStream的自己來避免: http://www.mfs-erp.org/blog/TZipFile-problem-accessing-open-files-even-with-TZipMode-zmRead