19

現在、SharpZipAPIを使用して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ステートメントは失敗します。バッファあり/なしで試してみました。誰かがその理由について何か洞察を与えることができますか?ファイル拡張子を確認できることは承知しています。それよりも決定的なものが必要です。zipには魔法の#(PK何か)があることも知っていますが、フォーマットの要件ではないため、常にそこにあるという保証はありません。

また、ネイティブzipをサポートする.net 4.5について読んだので、プロジェクトはsharpzipではなくそれに移行する可能性がありますが、CanDecompressEntryに似たメソッド/パラメーターはここに表示されませんでした:http://msdn.microsoft.com/en- us / library / 3z72378a%28v = vs.110%29

私の最後の手段は、try catchを使用して、ファイルの解凍を試みることです。

4

6 に答える 6

20

これは、非圧縮、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
        }
    }
}
于 2012-08-16T22:39:29.490 に答える
13

https://stackoverflow.com/a/16587134/206730リファレンスを見る

以下のリンクを確認してください。

isharpcode-sharpziplib-validate-zip ファイル

c# でファイルが圧縮されているかどうかを確認する方法

ZIP ファイルは常に 0x04034b50 (4 バイト) で始まります
詳細を表示: 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;
            }
        }

    }
于 2014-05-19T12:38:33.853 に答える
8

次のいずれかを実行できます。

  • try-catch 構造を使用して、潜在的な zip ファイルの構造を読み取ろうとします
  • ファイル ヘッダーを解析して、それが zip ファイルかどうかを確認します

ZIP ファイルは常に最初の 4 バイトが 0x04034b50 で始まります ( http://en.wikipedia.org/wiki/Zip_(file_format)#File_headers )

于 2012-08-16T22:26:20.173 に答える
2

Web 用にプログラミングしている場合は、ファイル Content Type: application/zip を確認できます。

于 2012-08-16T22:36:12.267 に答える