Expand the data file with DeflateStream

I'm having trouble reading a compressed (deflated) data file using C # .NET DeflateStream(..., CompressionMode.Decompress) . The file was written earlier using DeflateStream(..., CompressionMode.Compress) , and it looks just fine (I can even unzip it using the Java program).

However, the first call to Read() input stream to decompress / inflate the compressed data returns a length of zero (end of file).

Here is the main driver that is used for compression and decompression:

 public void Main(...) { Stream inp; Stream outp; bool compr; ... inp = new FileStream(inName, FileMode.Open, FileAccess.Read); outp = new FileStream(outName, FileMode.Create, FileAccess.Write); if (compr) Compress(inp, outp); else Decompress(inp, outp); inp.Close(); outp.Close(); } 

Here is the basic decompression code that doesn't work:

 public long Decompress(Stream inp, Stream outp) { byte[] buf = new byte[BUF_SIZE]; long nBytes = 0; // Decompress the contents of the input file inp = new DeflateStream(inp, CompressionMode.Decompress); for (;;) { int len; // Read a data block from the input stream len = inp.Read(buf, 0, buf.Length); //<<FAILS if (len <= 0) break; // Write the data block to the decompressed output stream outp.Write(buf, 0, len); nBytes += len; } // Done outp.Flush(); return nBytes; } 

A called FAILS call always returns zero. What for? I know that it should be something simple, but I just do not see it.

Here is the basic compression code that works just fine, and is almost exactly the same as the decompression method with replaced names:

 public long Compress(Stream inp, Stream outp) { byte[] buf = new byte[BUF_SIZE]; long nBytes = 0; // Compress the contents of the input file outp = new DeflateStream(outp, CompressionMode.Compress); for (;;) { int len; // Read a data block from the input stream len = inp.Read(buf, 0, buf.Length); if (len <= 0) break; // Write the data block to the compressed output stream outp.Write(buf, 0, len); nBytes += len; } // Done outp.Flush(); return nBytes; } 

solvable

After viewing the correct solution, the constructor operator should be changed to:

 inp = new DeflateStream(inp, CompressionMode.Decompress, true); 

which saves the open input stream, and the following line should be added after calling inp.Flush() :

 inp.Close(); 

Calling Close() causes the deflater thread to flush its internal buffers. The true flag prevents closing the underlying thread, which closes later in Main() . The same changes should be made to the Compress() method.

+4
source share
2 answers

In your unpacking method, reassign inp to the new stream (descent stream). You never close this Deflate stream, but you close the main file stream in Main (). A similar thing happens in the compression method.

I think the problem is that the main file stream closes before the deflation stream finalizers automatically close them.

I added 1 line of code to the Decompress and Compress: inp.Close () // methods in Decompressmehtod

outp.Close () // to the compression method.

best practice would be to include threads in the use clause.

Here's an alternative way to write your Decompress method (I tested and it works)

 public static long Decompress(Stream inp, Stream outp) { byte[] buf = new byte[BUF_SIZE]; long nBytes = 0; // Decompress the contents of the input file using (inp = new DeflateStream(inp, CompressionMode.Decompress)) { int len; while ((len = inp.Read(buf, 0, buf.Length)) > 0) { // Write the data block to the decompressed output stream outp.Write(buf, 0, len); nBytes += len; } } // Done return nBytes; }
public static long Decompress(Stream inp, Stream outp) { byte[] buf = new byte[BUF_SIZE]; long nBytes = 0; // Decompress the contents of the input file using (inp = new DeflateStream(inp, CompressionMode.Decompress)) { int len; while ((len = inp.Read(buf, 0, buf.Length)) > 0) { // Write the data block to the decompressed output stream outp.Write(buf, 0, len); nBytes += len; } } // Done return nBytes; } 
+4
source

I had the same problem with GZipStream, since we had the original length, I had to rewrite the code to read only the number of bytes expected in the source file.

I hope I'm going to find out that there was a better answer (fingers crossed).

0
source

All Articles