问题描述
我目前正在使用 SharpZip api 来处理我的 zip 文件条目.它适用于压缩和解压缩.但是,我无法确定文件是否为 zip.我需要知道是否有办法检测文件流是否可以解压缩.本来我用
I am currently using the SharpZip api to handle my zip file entries. It works splendid for zipping and unzipping. Though, I am having trouble identifying if a file is a zip or not. I need to know if there is a way to detect if a file stream can be decompressed. Originally I used
FileStream lFileStreamIn = File.OpenRead(mSourceFile);
lZipFile = new ZipFile(lFileStreamIn);
ZipInputStream lZipStreamTester = new ZipInputStream(lFileStreamIn, mBufferSize);// not working
lZipStreamTester.Read(lBuffer, 0, 0);
if (lZipStreamTester.CanDecompressEntry)
{
LZipStreamTester 每次都变为 null 并且 if 语句失败.我试过有/没有缓冲区.任何人都可以提供任何有关原因的见解吗?我知道我可以检查文件扩展名.我需要比这更明确的东西.我也知道 zip 有一个神奇的 #(PK something),但这并不能保证它会一直存在,因为它不是格式的要求.
The LZipStreamTester becomes null every time and the if statement fails. I tried it with/without a buffer. Can anybody give any insight as to why? I am aware that i can check for file extension. I need something that is more definitive than that. I am also aware that zip has a magic #(PK something), but it isn't a guarantee that it will always be there because it isn't a requirement of the format.
此外,我还读到了 .net 4.5 具有原生 zip 支持,因此我的项目可能会迁移到该 zip 而不是sharpzip,但我仍然需要在这里没有看到类似于 CanDecompressEntry 的方法/参数:http://msdn.microsoft.com/en-us/library/3z72378a%28v=vs.110%29一个>
Also i read about .net 4.5 having native zip support so my project may migrate to that instead of sharpzip but I still need didn't see a method/param similar to CanDecompressEntry here: http://msdn.microsoft.com/en-us/library/3z72378a%28v=vs.110%29
我最后的手段是使用 try catch 并尝试解压缩文件.
My last resort will be to use a try catch and attempt an unzip on the file.
推荐答案
这是组件的基类,该组件需要处理未压缩、PKZIP 压缩 (sharpziplib) 或 GZip 压缩(内置于 .net)的数据.也许比你需要的多一点,但应该能让你继续前进.这是使用@PhonicUK 的建议解析数据流标头的示例.您在小工厂方法中看到的派生类处理了 PKZip 和 GZip 解压的细节.
This is a base class for a component that needs to handle data that is either uncompressed, PKZIP compressed (sharpziplib) or GZip compressed (built in .net). Perhaps a bit more than you need but should get you going. This is an example of using @PhonicUK's suggestion to parse the header of the data stream. The derived classes you see in the little factory method handled the specifics of PKZip and GZip decompression.
abstract class Expander
{
private const int ZIP_LEAD_BYTES = 0x04034b50;
private const ushort GZIP_LEAD_BYTES = 0x8b1f;
public abstract MemoryStream Expand(Stream stream);
internal static bool IsPkZipCompressedData(byte[] data)
{
Debug.Assert(data != null && data.Length >= 4);
// if the first 4 bytes of the array are the ZIP signature then it is compressed data
return (BitConverter.ToInt32(data, 0) == ZIP_LEAD_BYTES);
}
internal static bool IsGZipCompressedData(byte[] data)
{
Debug.Assert(data != null && data.Length >= 2);
// if the first 2 bytes of the array are theG ZIP signature then it is compressed data;
return (BitConverter.ToUInt16(data, 0) == GZIP_LEAD_BYTES);
}
public static bool IsCompressedData(byte[] data)
{
return IsPkZipCompressedData(data) || IsGZipCompressedData(data);
}
public static Expander GetExpander(Stream stream)
{
Debug.Assert(stream != null);
Debug.Assert(stream.CanSeek);
stream.Seek(0, 0);
try
{
byte[] bytes = new byte[4];
stream.Read(bytes, 0, 4);
if (IsGZipCompressedData(bytes))
return new GZipExpander();
if (IsPkZipCompressedData(bytes))
return new ZipExpander();
return new NullExpander();
}
finally
{
stream.Seek(0, 0); // set the stream back to the begining
}
}
}
这篇关于C#.net 识别zip文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!