How to read from a file containing multiple GzipStreams

I have a file created with code that looks like this:

        using (var fs=File.OpenWrite("tmp"))
        {
            using (GZipStream gs=new GZipStream(fs,CompressionMode.Compress,true))
            {
                using (StreamWriter sw=new StreamWriter(gs))
                {
                    sw.WriteLine("hello ");
                }
            }

            using (GZipStream gs = new GZipStream(fs, CompressionMode.Compress, true))
            {
                using (StreamWriter sw = new StreamWriter(gs))
                {
                    sw.WriteLine("world");
                }
            }
        }

Now I am trying to read data from this file with the following code:

        string txt;

        using (var fs=File.OpenRead("tmp"))
        {
            using (GZipStream gs=new GZipStream(fs,CompressionMode.Decompress,true))
            {
                using (var rdr = new StreamReader(gs))
                {
                    txt = rdr.ReadToEnd();
                }
            }

            using (GZipStream gs = new GZipStream(fs, CompressionMode.Decompress, true))
            {
                using (StreamReader sr = new StreamReader(gs))
                {
                    txt+=sr.ReadToEnd();
                }
            }
        }

The first stream is read normally, but the second stream is not read.

How can I read the second stream?

+5
source share
4 answers

, GzipStream gzip gzip. (, , gzip winzip, , ). , , DotNetZip (http://dotnetzip.codeplex.com/).

, gzip, . , ID1, ID2 0x8 ( Deflate, . : http://www.gzip.org/zlib/rfc-gzip.html). , , gzip, (, , ), :

    const int Id1 = 0x1F;
    const int Id2 = 0x8B;
    const int DeflateCompression = 0x8;
    const int GzipFooterLength = 8;
    const int MaxGzipFlag = 32; 

    /// <summary>
    /// Returns true if the stream could be a valid gzip header at the current position.
    /// </summary>
    /// <param name="stream">The stream to check.</param>
    /// <returns>Returns true if the stream could be a valid gzip header at the current position.</returns>
    public static bool IsHeaderCandidate(Stream stream)
    {
        // Read the first ten bytes of the stream
        byte[] header = new byte[10];

        int bytesRead = stream.Read(header, 0, header.Length);
        stream.Seek(-bytesRead, SeekOrigin.Current);

        if (bytesRead < header.Length)
        {
            return false;
        }

        // Check the id tokens and compression algorithm
        if (header[0] != Id1 || header[1] != Id2 || header[2] != DeflateCompression)
        {
            return false;
        }

        // Extract the GZIP flags, of which only 5 are allowed (2 pow. 5 = 32)
        if (header[3] > MaxGzipFlag)
        {
            return false;
        }

        // Check the extra compression flags, which is either 2 or 4 with the Deflate algorithm
        if (header[8] != 0x0 && header[8] != 0x2 && header[8] != 0x4)
        {
            return false;
        }

        return true;
    }

, GzipStream , . MemoryStream, .

gzip, , ( ), gzip.

+4

GzipStream. RFC 1952 gzip:

2,2.

gzip "" ( ). . , , .

, gzip gzip.

, GzipStream gzip, GzipStream, gzip, , GzipStream. , gzip.

, , gzip, gzip. , , , gzip, gzip, , ( , , ), fux gzip gzip.

DotNetZip. GzipStream , NET 4.5, , , . Microsoft , , . DotNetZip .

+5

DeflateStream.

, , - , Read (byte [] buffer, int offset, int count). DeflateStream/GZipStream, , . , Read, .

DeflateStream, , reset Inflater.

+2

I checked that SharpZipLib 0.86.0.518 can read files with multiple gzip members:

using (var fileStream = File.OpenRead(filePath))
using (var gz = new GZipInputStream(fileStream))
{
    //Read from gz here
}

You can get it with NuGet.

0
source

All Articles