GZipStream Constructor (stream, mode) doesn't work

Aug 10, 2011 at 9:35 AM

sample:

using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
{
    using (var raw = System.IO.File.Create(outputFile))
    {
        using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))
        {
            byte[] buffer = new byte[WORKING_BUFFER_SIZE];
            int n;
            while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
            {
                compressor.Write(buffer, 0, n);
            }
        }
    }
}

 

And what I use this Constructor:

public Stream Zip(Stream ToCompress)//压缩
        {
            using (Stream input = ToCompress)
            {
                using (Stream raw = outputFile)
                {
                    using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))
                    {
                        byte[] buffer = new byte[outputFile.Length];
                        int n;
                        while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            compressor.Write(buffer, 0, n);
                        }
                    }
                    return raw;
                }
            }
        }

this comes a Exception——PlatformNotSupportedException.

but you say ——DotNetZip is built for the .NET Compact Framework (v2.0 or later) as well as for the regular .NET Framework (v2.0 or later). This means you can build a Smart Device application in Visual Studio 2008, that uses the capabilities of DotNetZip.

Now, I doubt whether GZipStream Constructor (stream, mode) can use in the .net cf?

hope for your reply.

thanks.

 

Coordinator
Aug 10, 2011 at 1:34 PM

The GZipStream uses a text encoding, iso-8859-1, which is not supported in all CF platforms.  Some device OS platforms support it, some don't.  The exception you are getting is because of that.

I've since implemented an encoding class to workaround this pitfall. It will be in a future release of DotNetZip, and will allow all .NET CF platforms to use GZipStream.

see http://dotnetzip.codeplex.com/workitem/14045 (It mentions Silverlight, but it applies to Compact Framework as well)

If you are willing to test the fix, let me know, and I will produce a build for you.

 

Aug 10, 2011 at 1:58 PM

Hey I was wondering as well when you will release a build with that fix. Thanks

Coordinator
Aug 11, 2011 at 5:10 AM

ok I posted a build there on the workitem, give it a try and let me know.

http://dotnetzip.codeplex.com/workitem/14045

 

Aug 11, 2011 at 5:21 AM

thanks,Cheeso

I can't believe you reply me so fast,thank you very much.

Now I will have a try.

 

Aug 11, 2011 at 5:40 AM
Edited Aug 11, 2011 at 6:41 AM

Cheeso,

use this http://dotnetzip.codeplex.com/workitem/14045 , sovled the exception of PlatformNotSupportedException. thank you again.

also, I need you help. 

Also, I need you help. 

private Stream outputFile;

public Stream Zip(Stream ToCompress)//压缩
        {
            using (Stream input = ToCompress)
            {
                using (Stream raw = outputFile)
                {
                    using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))
                    {
                        byte[] buffer = new byte[outputFile.Length];
                        int n;
                        while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            compressor.Write(buffer, 0, n);
                        }
                    }
                    return raw;
                }
            }
        }

Is I use right?  I konw outputFile is null,but I don't konw how to modify?

FileToCompress and outputFile are filename?what's the outputFile meaning?

Isn't GZipStream  a stream compression? why it need filename

Aug 11, 2011 at 6:41 AM

Also, I need you help. 

private Stream outputFile;

public Stream Zip(Stream ToCompress)//压缩
        {
            using (Stream input = ToCompress)
            {
                using (Stream raw = outputFile)
                {
                    using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))
                    {
                        byte[] buffer = new byte[outputFile.Length];
                        int n;
                        while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            compressor.Write(buffer, 0, n);
                        }
                    }
                    return raw;
                }
            }
        }

Is I use right?  I konw outputFile is null,but I don't konw how to modify?

FileToCompress and outputFile are filename?what's the outputFile meaning?

Isn't GZipStream  a stream compression? why it need filename.

Coordinator
Aug 11, 2011 at 10:07 AM
Edited Aug 11, 2011 at 2:05 PM

No - your code is not quite right. 

You must not use a using clause, if you will return the stream from the method.  See below.

  public Stream Zip(Stream ToCompress)//压缩
  {
      using (Stream input = ToCompress)
      {
          // get an output stream here.  Because this method
          // RETURNS the stream, it must not be initialized within
          // a using clause!  A using clause would close and
          // dispose the stream at scope exit, which means, the
          // returned Stream would be disposed before the caller
          // could reference it.
          Stream raw = new MemoryStream(); 

          using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))
          {
              byte[] buffer = new byte[outputFile.Length 2048];
              int n;
              while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
              {
                  compressor.Write(buffer, 0, n);
              }
          }
          // may want to Seek() on the stream here, or 
          // maybe not. Make a decision.
          return raw;
      }
  }

Aug 11, 2011 at 12:05 PM

public Stream Zip(Stream ToCompress)//压缩
  {
      using (Stream input = ToCompress)
      {
          // get an output stream here.  Because this method
          // RETURNS the stream, it must not be initialized within
          // a using clause!  A using clause would close and
          // dispose the stream at scope exit, which means, the
          // returned Stream would be disposed before the caller
          // could reference it.
          Stream raw = new MemoryStream();

          using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))
          {
              byte[] buffer = new byte[outputFile.Length];
              int n;
              while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
              {
                  compressor.Write(buffer, 0, n);
              }
          }
          // may want to Seek() on the stream here, or
          // maybe not. Make a decision.
          return raw;
      }
  }
what's the ToCompress and outputFile means? a file?if I want to use they as stream,how to modify?

Aug 11, 2011 at 1:33 PM

First I have a try in the .NET windowsApplication,there is some problem:

using (System.IO.Stream input = System.IO.File.OpenRead("c:\\123.txt"))//input's length = 6

            {
                using (System.IO.Stream raw = System.IO.File.Create("c:\\456.zip"))
                {
                    using (System.IO.Stream compressor = new GZipStream(raw, CompressionMode.Compress))// but Length = “compressor.Length”引发了“System.NotImplementedException”类型的异常
                    {
                        byte[] buffer = new byte[raw.Length];
                        int n;
                        while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            compressor.Write(buffer, 0, n);
                        }
                    }
                }
            }

Then I more doubt how I can change this GZipStream Constructor to .NET CF,use stream?

Hope your help,thanks.

Coordinator
Aug 11, 2011 at 2:04 PM

No - what you are doing is not correct.

First, GZipStream does not create zip files.  You must not name the file "C:\\456.zip".  It is not a zip file, you will only confuse yourself and others if you use misleading (incorrect) file extensions.

The output of a GZipStream is typically stored in a file with extension .gz. 

Ok, next - when you copy the stream, you should not use raw.Length as the size of the buffer to use.  For two reasons.  #1. In this case raw is the name of the OUTPUT STREAM.  The length of that stream is irrelevant - in fact the actual length at the time you invoke raw.Length is ZERO, because nothing has been written to the output stream at that point.  #2.  you must not use a buffer size equal to the size of the file.  Use a small buffer size - something like 1024 bytes is fine, 8192 bytes is fine.   Use a specific number there.

You should not be using (reading) compressor.Length either.  In the code I posted in my previous reply, I REPEATED THE ERROR THAT YOU HAD IN YOUR CODE.  Do not follow that example.  This is better:

  public Stream Zip(Stream ToCompress)
  {
      using (Stream input = ToCompress)
      {
          // get an output stream here.  Because this method
          // RETURNS the stream, it must not be initialized within
          // a using clause!  A using clause would close and
          // dispose the stream at scope exit, which means, the
          // returned Stream would be disposed before the caller
          // could reference it.
          Stream raw = new MemoryStream();

          using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))
          {
              byte[] buffer = new byte[1024];
              int n;
              while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
              {
                  compressor.Write(buffer, 0, n);
              }
          }
          // may want to Seek() on the stream here, or
          // maybe not. Make a decision.
          return raw;
      }
  }

Aug 11, 2011 at 3:01 PM
  public Stream Zip(Stream ToCompress)
  {
      using (Stream input = ToCompress)
      {
          Stream raw = new MemoryStream();

          using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))   //Length = “compressor.Length”引发了“System.NotImplementedException”类型的异常
          {
              byte[] buffer = new byte[1024];
              int n;
              while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
              {
                  compressor.Write(buffer, 0, n);
              }
          }
          // may want to Seek() on the stream here, or
          // maybe not. Make a decision.
          return raw;
      }
  }

Coordinator
Aug 11, 2011 at 3:59 PM

??? Is there a question in there somewhere?

Aug 11, 2011 at 4:14 PM

public Stream Zip(Stream ToCompress)
  {
      using (Stream input = ToCompress)
      {
          Stream raw = new MemoryStream();

          using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))   //Length = “compressor.Length”引发了“System.NotImplementedException”类型的异常
          {
              byte[] buffer = new byte[1024];
              int n;
              while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
              {
                  compressor.Write(buffer, 0, n);
              }
          }
          // may want to Seek() on the stream here, or
          // maybe not. Make a decision.
          return raw;
      }
  }
the red word means Length = “compressor.Length”引发了“System.NotImplementedException”类型的异常.

this means compress is failed, right?

there is something what I want to say:

first ,I 'm sorry for my mistakes——byte[] buffer = new byte[outputFile.Length 2048];
second ,thanks for your patient to help me .

I'm a newer,something I don't feel well.thanks for your help again.

Coordinator
Aug 11, 2011 at 4:29 PM

I don't know what you mean - "this means compress is failed". 

If there is an exception, you need to post the exception stacktrace.   The full stacktrace.

Take care to use the correct version of the code.

 

Aug 12, 2011 at 2:51 AM

stream compress stream:

 public Stream Zip(Stream ToCompress)
        {
            using (Stream input = ToCompress)
            {
                Stream raw = new MemoryStream();
                using (Stream compressor = new GZipStream(raw, CompressionMode.Compress)) 
                {
                    byte[] buffer = new byte[2048];
                    int n;
                    while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        compressor.Write(buffer, 0, n);
                    }
                }
                return raw;
            }
        }

public string PostZips(string url, Stream zips)
{
byte[] bytes = new byte[zips.Length];
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
……
if (proxyUse)
{
 request.Proxy = new WebProxy("http:……");
}
request.Method = "POST";
request.ContentLength = bytes.Length;
request.ContentType = "gz";
}

 

errpr:

1) using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))——Length = “compressor.Length”引发了“System.NotImplementedException”类型的异常,

位于 Ionic.Zlib.GZipStream.get_Length()
位于 SJGJ_PPC.clsZip.Zip()
位于 SJGJ_PPC.InfoMobileForm.BackupContacts()
位于 SJGJ_PPC.InfoMobileForm.BackupContacts()

2)raw——Length = “raw.Length”引发了“System.ObjectDisposedException”类型的异常,

位于 System.IO.__Error.StreamIsClosed()
位于 System.IO.MemoryStream.get_Length()
位于 SJGJ_PPC.clsZip.Zip()
位于 SJGJ_PPC.InfoMobileForm.BackupContacts()
位于 SJGJ_PPC.InfoMobileForm.BackupContacts()

3)byte[] bytes = new byte[zips.Length];——bytes = null

Then I can't post this Stream to server.

 

 

Aug 12, 2011 at 6:15 AM

I try to modify, it sees work well:

public byte[] Zip(string ToCompress)//Stream压缩Stream
{
 using (Stream input = StringToMemoryStream(ToCompress))
 {
  MemoryStream raw = new MemoryStream();
  using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))
  {
   byte[] buffer = new byte[2048];
   int n;
   while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
   {
    compressor.Write(buffer, 0, n);
   }
   byte[] bytes = raw.ToArray(); 

    return bytes;
  }
 }
}
byte[] bytes = raw.ToArray(); ——prevent the System.ObjectDisposedException. Then the byte has num,byte = 10.

It sees work well now,Thanks.