UTF-8文件名的Zip文件

7

在我的网站上,我有一个选项可以下载用户上传的所有图片。问题在于带有希伯来语名称的图片(我需要文件的原始名称)。我尝试解码文件名,但这并没有帮助。以下是代码:

using ICSharpCode.SharpZipLib.Zip;

Encoding iso = Encoding.GetEncoding("ISO-8859-1");
Encoding utf8 = Encoding.UTF8;
byte[] utfBytes = utf8.GetBytes(file.Name);
byte[] isoBytes = Encoding.Convert(utf8, iso, utfBytes);
string name = iso.GetString(isoBytes);

var entry = new ZipEntry(name + ".jpg");
zipStream.PutNextEntry(entry);
using (var reader = new System.IO.FileStream(file.Name, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    byte[] buffer = new byte[ChunkSize];
    int bytesRead;
    while ((bytesRead = reader.Read(buffer, 0, buffer.Length)) > 0)
    {
        byte[] actual = new byte[bytesRead];
        Buffer.BlockCopy(buffer, 0, actual, 0, bytesRead);
        zipStream.Write(actual, 0, actual.Length);
    }
} 

在对文件名进行UTF-8编码后,我得到了希伯来语的文件名:??????.jpg。我做错了什么?

什么是新的 ZipEntry?我不知道它是否是新的 System.IO.Compression 命名空间的一部分。J#? - efkah
这是ICSharpCode.SharpZipLib.Zip库。 - freethinker
3个回答

2

Unicode(UTF-8是其中一种二进制编码)可以表示的字符比其他8位编码更多。此外,您不是在进行正确的转换,而是在重新解释,这意味着您会得到垃圾文件名。您应该真正阅读Joel on Unicode这篇文章。

...

现在您已经阅读了这篇文章,您应该知道在C#中,字符串可以存储Unicode数据,因此如果库未包含编码处理错误(这总是可能的),则您可能不需要对file.Name进行任何转换,并且可以直接将其传递给ZipEntry构造函数。


嗨。感谢回复和文章。如果我不执行编码块,我的压缩文件中的文件名会像这样:ëàâàüëò Çàîé_1.jpg - freethinker

1
尝试使用 <\p>。
ZipStrings.UseUnicode = true;

它应该是ICSharpCode.SharpZipLib.Zip命名空间的一部分。
之后,您可以使用类似以下内容的东西。
var newZipEntry = new ZipEntry($"My ünicödë string.pdf");

并将该条目像常规一样添加到流中。在C#中,您不需要在此之前对字符串进行任何转换。


0

你正在进行错误的转换,因为C#中的字符串已经是Unicode格式的。 你使用什么工具来检查存档文件中的文件名? 默认情况下,Windows ZIP实现使用系统DOS编码来处理文件名,而其他实现可能会使用其他编码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接