当我尝试检查zip文件的有效性时,会引发一个异常,即该进程无法访问该文件,因为它正由另一个进程使用,但Open1.Click中的代码打开zip文件没有问题。 Valid1Click有什么问题吗?
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;
答案 0 :(得分:3)
你有这些错误的方法:
iZipFile.Open(iZipFilename, zmRead);
iValid := iZipFile.IsValid(iZipFilename);
第一行锁定文件,因此第二行失败。在致电IsValid
之前,您必须致电Open
。
话虽如此,由于您使用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 :(得分:0)
正如David Heffernan最初所说:在TZipFile :: Open(文件名,模式)之后应该可以使用isValid,因为人们会期望打开一个只读文件不会阻止其他人阅读。
当使用基于fileNAME的Open方法(另一个存在用于从TFileStream读取f)时,它在内部创建一个fileStream,而当它 指定fmOpenRead时,它不在打开此流时设置共享模式。
请参阅此博客文章,了解如何通过首先自己创建TFileStream来明确指定共享模式的示例: http://www.mfs-erp.org/blog/TZipFile-problem-accessing-open-files-even-with-TZipMode-zmRead