当您尝试读取TZipFile.FileComment时,编译器报告这将无法编译: [dcc64错误] Unit1.pas(451):E2010不兼容的类型:'string'和'System.TArray'
var
iFileComment: string;
...
iFileComment := iZipFile.FileInfo[i].FileComment;
那么......你如何阅读TZipFile注释并将其分配给字符串?这看起来很奇怪,因为我可以成功编写zipfile注释,如下所示:
iZipFile.FileComment[ListView1.ItemIndex] := FileComment1.Text;
如果您尝试阅读评论:
iFileComment := iZipFile.FileComment[i];
zip文件中的每个文件都有相同的注释,即使只有一个文件实际上有文件注释。
评论由此添加:
procedure TForm1.SetFileComment1Click(Sender: TObject); var
iZipFile: TZipFile; iListItem: TlistItem;
begin
if ListView1.ItemIndex <> -1 then
begin
iZipFile := TZipFile.Create;
try
{ Open zip file for writing }
iZipFile.Open(ZipFilename1.Text, zmReadWrite);
iZipFile.FileComment[ListView1.ItemIndex] := FileComment1.Text;
{ Close the zip file }
iZipFile.Close;
{ Update the listview }
ListView1.Items.BeginUpdate;
try
iListItem := ListView1.Items.Item[ListView1.ItemIndex];
iListItem.SubItems[5] := FileComment1.Text;
finally
ListView1.Items.EndUpdate;
end;
finally
iZipFile.Free;
end;
end
else
begin
MessageBox(0, 'A filename is not selected. Please select a filename.',
'Warning', MB_ICONINFORMATION or MB_OK);
end;
end;
修改
我现在按照建议使用iZipFile.FileComment [Index]设置和编写文件评论。 当我设置一个文件的注释并在工作的zip应用程序中打开zip文件时,只有我设置的单个文件带有注释...在这个TZipFile项目中,当我加载相同的zip文件时,每个文件都有相同的注释但我看不出原因。除了filecomment字段之外,所有其他字段都按预期运行。
以下是打开zip文件的代码:
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
{ Open zip file for reading }
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.FileComment[i];
iListItem.SubItems.Add(iFileComment); { 5 }
end;
{ Close the zip file }
iZipFile.Close;
except
on E: Exception do
begin
ShowMessage(E.ClassName + #10#13 + E.Message);
end;
end;
finally
iZipFile.Free;
end;
end;
end;
end;
答案 0 :(得分:4)
你以与写作相同的方式阅读它,反过来:
// Write the comment
iZipFile.FileComment[Index] := 'This is a zip file comment';
// Read it back
sComment := iZipFile.FileComment[Index];
WriteLn(sComment); // Outputs "This is a zip file comment"
Index
将匹配zip存档中单个文件的索引。换句话说,第一个文件位于索引0,第二个文件位于索引1,等等,最后一个文件位于索引FileCount - 1
。
这是一个有效的例子。我创建了一个名为Test.zip
的虚拟zip文件,其中包含我在答案中使用的一些旧的.png文件(如下图所示):
然后我使用下面的代码为每个文件添加注释并将其读回,并将它们写入控制台:
program Project1;
{$APPTYPE CONSOLE}
uses
System.SysUtils, System.Zip;
var
Zip: TZipFile;
i: Integer;
begin
Zip := TZipFile.Create;
Zip.Open('D:\TempFiles\Test.zip', zmReadWrite);
for i := 0 to Zip.FileCount - 1 do
Zip.FileComment[i] := Format('This is file %d', [i]);
Zip.Free; // Flushes changes to disk automatically
// Create a new instance, just to make it clear.
Zip := TZipFile.Create;
Zip.Open('D:\TempFiles\Test.zip', zmReadWrite);
for i := 0 to Zip.FileCount - 1 do
WriteLn(Zip.FileNames[i] + ':'#9 + Zip.FileComment[i]);
Zip.Free;
ReadLn;
end.
这是它产生的输出:
这是它添加的zip文件评论,如7Zip:
中所示
答案 1 :(得分:4)
在XE2中,TZipHeader.FileComment
被声明为RawByteString
,可以直接分配给String
(使用类型转换来避免编译器警告):
iFileComment := String(iZipFile.FileInfo[i].FileComment);
但是,在XE4中,TZipHeader.FileComment
被声明为TBytes
。您不能直接将TBytes
分配给String
(反之亦然),而是编译错误。
如果您查看XE4中TZipFile.GetFileComment()
的实现,则会使用TZipFile.TBytesToString()
将TBytes
转换为String
。 TZipFile.TBytesToString()
使用SysUtils.TEncoding.GetString()
进行实际转化,使用代码页65001或437,具体取决于TZipFile.UTF8Support
属性的值。
获取/设置每个文件注释的正确方法是使用TZipFile.FileComments[]
属性,如Ken演示。它不仅为您处理字符串&lt; - &gt;字节转换,而且还会在访问数据之前检查zip是否已打开。
答案 2 :(得分:0)
很抱歉重新提出这个旧问题,但没有一个答案实际上解决了 zip文件中的每个文件都有相同的评论问题。
TZipFile.ReadCentralHeader
打开zip文件时ReadCentralHeader
将所有zip目录条目读入内部记录列表,但无法清除每个条目之间用于填充列表的临时记录。
如果文件注释ReadCentralHeader
首先读取FileCommentLength
值,但如果此值为零,则它不会设置FileComment
值的值,因此保留上一个条目的值。
可能的解决方法是在阅读FileCommentLength
属性时考虑FileComment[]
值:
Comment := Copy(ZipFile.FileComment[Index], 1, ZipFile.FileInfo[Index].FileCommentLength);