1

圧縮ファイルから圧縮されていないすべてのバイトを返すメソッドを作成しました。

    public static byte[] GetAllBytesFromCompressedFile(string fullPath)
    {
        const int blockSize = 10000;
        byte[] block = new byte[blockSize];
        List<byte> allBytes = new List<byte>(blockSize);

        int counter = 0;
        using (FileStream file = new FileStream(fullPath, FileMode.Open))
        {
            using (DeflateStream compress = new DeflateStream(file, CompressionMode.Decompress))
            {
                int bytesRead = 0;
                do
                {
                    bytesRead = compress.Read(block, 0, blockSize);
                    counter += bytesRead;
                    allBytes.AddRange(block);
                } while (bytesRead == blockSize);
            }
        }

        return allBytes.GetRange(0, counter).ToArray();
    }

正常に動作しますが、ループ内で数百万回呼び出される可能性があります。ほとんどのファイルはかなり小さいですが、最大で約 100Mb のものもあり、すべての小さなファイルに 100Mb を事前に割り当てたくありませんでした。だから私はいくつかの質問があります:

  1. まず、このようなメソッドはフレームワークに既にありますか? または、これを行うより良い方法はありますか?
  2. 圧縮ファイルの非圧縮サイズを取得する方法はありますか? (そうすれば、ループ内でブロックを取得する必要がなくなり、Read1回呼び出すことができます)
  3. 使用List<byte>したので、手動でバイト配列を再割り当てする必要はありません。バイトを追加するより効率的な方法はありますか?

ほとんどの人にとって難しい問題ではないかもしれませんが、新しいコードをここに置きます。しかし、誰かがバッファサイズを明示的に設定するなど、改善できる何かを見つけるかもしれません(?)

    public static byte[] GetAllBytesFromCompressedFile(string fullPath)
    {
        using (MemoryStream allBytes = new MemoryStream())
        {
            using (FileStream file = new FileStream(fullPath, FileMode.Open))
            {
                using (DeflateStream compress = new DeflateStream(file, CompressionMode.Decompress))
                {
                    compress.CopyTo(allBytes);
                }
            }

            return allBytes.ToArray();
        }
    }
4

1 に答える 1

4

まず、このようなメソッドはフレームワークに既にありますか? または、これを行うより良い方法はありますか?

aMemoryStreamをバッファとして使用し、 を使用Stream.Copyしてデータを 1 行にコピーします。

圧縮ファイルの非圧縮サイズを取得する方法はありますか?

いいえ、deflate はストリーミング形式です。圧縮されていないデータは圧縮された入力よりも大きくなる可能性が高いため、何らかの値を推測できます。これを行うのはおそらく時間の無駄です。

リストを使用したので、バイト配列を手動で再割り当てする必要はありません。バイトを追加するより効率的な方法はありますか?

これは恐ろしく非効率的です。クラスは、List渡されたバイト配列を列挙し、バイトを 1 つずつ追加します。大きなファイルでCPUを狂ったように燃やします。を使用しMemoryStreamます。memcpyコピー操作を実行するために使用します。

また、バグがあります。読み取りからの戻り値を使用して、読み取られたバイト数を判断していません。常に 1 つの完全なバッファーを追加しています。これは、提案されたアルゴリズムではなくなります。

于 2014-05-21T14:02:23.797 に答える