【发布时间】:2011-04-10 04:25:09
【问题描述】:
我正在尝试对应用程序实施文件压缩。该应用程序已经存在了一段时间,因此它需要能够读取以前版本编写的未压缩文档。我希望 DeflateStream 能够处理未压缩的文件,但对于 GZipStream 我得到“GZip 标头中的幻数不正确”错误。对于 DeflateStream,我得到“解码时发现无效数据”。我猜它没有找到将文件标记为它的类型的标头。
如果不能简单地处理未压缩的文件,那么第二好的方法是确定文件是否被压缩,并选择读取文件的方法。我找到了这个链接:http://blog.somecreativity.com/2008/04/08/how-to-check-if-a-file-is-compressed-in-c/,但这是非常具体的实现,感觉不是正确的方法。它还可以提供误报(我确信这种情况很少见,但它确实表明这不是正确的方法)。
我考虑的第三个选项是尝试使用 DeflateStream,如果发生异常则回退到正常的流 IO。这也让人感觉很混乱,并导致 VS 在异常处中断(除非我取消选中该异常,我真的不想这样做)。
当然,我可能只是走错了路。这是我在 .Net 3.5 中尝试过的代码:
Stream reader = new FileStream(fileName, FileMode.Open, readOnly ? FileAccess.Read : FileAccess.ReadWrite, readOnly ? FileShare.ReadWrite : FileShare.Read);
using (DeflateStream decompressedStream = new DeflateStream(reader, CompressionMode.Decompress))
{
workspace = (Workspace)new XmlSerializer(typeof(Workspace)).Deserialize(decompressedStream);
if (readOnly)
{
reader.Close();
workspace.FilePath = fileName;
}
else
workspace.SetOpen(reader, fileName);
}
有什么想法吗?
谢谢! 卢克。
【问题讨论】:
-
为您的新文件格式使用不同的文件名或扩展名怎么样?
-
我想这会起作用(作为一个标志),但宁愿避免 if poss,这样最终用户就不必知道他们文档的多个文件扩展名。我也很想知道是否有人有任何其他解决方案,只是想知道这是否是.Net的限制,或者我是否做错了什么。不过谢谢!
-
“试图确定”文件是否被压缩(通过熵、检查非 ascii 字符等)是在自找麻烦。你需要一个合适的文件头。压缩整个文件意味着它不再是 XML 文档(旧版本的应用程序会试图阅读它),所以你没有理由不能添加标题 :)
标签: c# .net compression stream