C#.net SharpZip 解压缩 如何识别 zip 文件

.Net技术 针尖舞 6年前 (2015-07-26) 1795次浏览 0个评论

目前,我在使用 SharpZip api 来处理我的 zip 文件实体。它压缩和解压缩时工作很出色。不过,我遇到的麻烦是如何确定文件是不是 zip 。我需要知道是否有一种方法探测文件流是否可以被解压缩。最初我使用如下方式:
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语句失败, 有没有 buffer的情况我都尝试了。谁能告诉我为什么,或者别的任何见解吗?我知道可以检查文件扩展名。我需要一些比这更为明确的方法。我也意识到 zip 具有神奇的 #(PK ), 但是并不能保证总是存在,因为这并不是必须的格式。
我也读到 .net 4.5有原生zip支持,所以我的项目可能会迁移到 .net 4.5 ,替换掉sharpzip。但是在这里我仍然没有看到类似CanDecompressEntry的方法/参数: http://msdn.microsoft.com/en-us/library/3z72378a%28v=vs.110%29
最后我只能使用try catch尝试解压文件。

3票

这是一个处理数据解压缩,PKZIP压缩(sharpziplib)或GZip压缩(在. net创建)组件的基类。可能比你需要的功能多一点。这是一个使用@PhonicUK的建议来解析数据流的头的例子。你看到的工厂方法中的派生类是用来处理PKZip和GZip解压缩的细节。

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
        }
    }
}
7票

你也可以这样:

    • 使用try – catch结构并试图读取一个潜在的zip文件的结构
    • 解析文件头,看看这是不是一个zip文件

ZIP文件总是从0x04034b50开始作为它的前4个字节( http://en.wikipedia.org/wiki/Zip_(file_format)#File_headers )

6票
参考http://stackoverflow.com/a/16587134/206730 链接
参考下面链接:
icsharpcode-sharpziplib-validate-zip-file
How-to-check-if-a-file-is-compressed-in-c#
ZIP文件总是从0x04034b50开始(4 bytes)查看更多: http://en.wikipedia.org/wiki/Zip_(file_format)#File_headers
使用例子:

        bool isPKZip = IOHelper.CheckSignature(pkg, 4, IOHelper.SignatureZip);
        Assert.IsTrue(isPKZip, "Not ZIP the package : " + pkg);
// http://blog.somecreativity.com/2008/04/08/how-to-check-if-a-file-is-compressed-in-c/
    public static partial class IOHelper
    {
        public const string SignatureGzip = "1F-8B-08";
        public const string SignatureZip = "50-4B-03-04";
        public static bool CheckSignature(string filepath, int signatureSize, string expectedSignature)
        {
            if (String.IsNullOrEmpty(filepath)) throw new ArgumentException("Must specify a filepath");
            if (String.IsNullOrEmpty(expectedSignature)) throw new ArgumentException("Must specify a value for the expected file signature");
            using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                if (fs.Length < signatureSize)
                    return false;
                byte[] signature = new byte[signatureSize];
                int bytesRequired = signatureSize;
                int index = 0;
                while (bytesRequired > 0)
                {
                    int bytesRead = fs.Read(signature, index, bytesRequired);
                    bytesRequired -= bytesRead;
                    index += bytesRead;
                }
                string actualSignature = BitConverter.ToString(signature);
                if (actualSignature == expectedSignature) return true;
                return false;
            }
        }
    }
2票
如果你是web网络编程,你可以检查文件Content Type: application/zip

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C#.net SharpZip 解压缩 如何识别 zip 文件
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!