为何我用System.IO.Compression.GZipStream解压缩,速度这么慢?

时间:2022-08-23 20:00:15
写出如下的代码,让我很是费力。
.net 提供了System.IO.Compression.GZipStream的压缩示例,却没有很好的解压缩的代码。
无奈自己实现了一段,但是在解压一段压缩后成为1.16MB,而原始数据为15MB的数据时,
竟耗时达3000毫秒左右!

不知原因为何,请高手不禀赐教!因为本人新号,分值有限,还望大家谅解!

先贴一下代码:

        public object DeCompression(byte[] request)
        {
            object ob = new object();
            Stream sourceStream = new MemoryStream(request);
            System.IO.Compression.GZipStream zipStream = new System.IO.Compression.GZipStream(
                sourceStream,
                System.IO.Compression.CompressionMode.Decompress);

            byte[] buffer = new byte[20480];
            byte[] bt = new byte[0];
            int iread = 0;
            do
            {
                iread = zipStream.Read(buffer, 0, 20480);
                byte[] bswap = new byte[bt.Length + buffer.Length];
                Buffer.BlockCopy(bt, 0, bswap, 0, bt.Length);
                Buffer.BlockCopy(buffer, 0, bswap, bt.Length, buffer.Length);
                bt = bswap;
                bswap = null;
                GC.Collect();
            } while (iread > 0);

            zipStream.Close();
            sourceStream.Close();
            MemoryStream ms = new MemoryStream(bt);
            ob = DeSerializeBinary(ms);
            ms.Close();
            return ob;
        }



10 个解决方案

#1


public static void DeCompress(string fileName, string dirPath)
        {
            using (Stream source = File.OpenRead(fileName))
            {
                using (Stream destination = new MemoryStream())
                {
                    using (GZipStream input = new GZipStream(source, CompressionMode.Decompress, true))
                    {
                        byte[] bytes = new byte[4096];
                        int n;
                        while ((n = input.Read(bytes, 0, bytes.Length)) != 0)
                        {
                            destination.Write(bytes, 0, n);
                        }
                    }
                    destination.Flush();
                    destination.Position = 0;
                    DeSerializeFiles(destination, dirPath);
                }
            }
        }

using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.GZip;
string []FileProperties=new string[2];
FileProperties[0]=strPath; //待解压的文件
FileProperties[1]=strPath+@"\";//解压后放置的目标目录
UnZip(FileProperties);


public void UnZip(string[] args)
{
ZipInputStream s = new ZipInputStream(File.OpenRead(args[0]));
   
ZipEntry theEntry;// = s.GetNextEntry();
while ((theEntry = s.GetNextEntry()) != null)  
{
string directoryName = Path.GetDirectoryName(args[1]);
string fileName = Path.GetFileName(theEntry.Name);
Directory.CreateDirectory(directoryName);
if (fileName != String.Empty)  
{   
//解压文件到指定的目录

FileStream streamWriter = File.Create(args[1]+theEntry.Name);
    
int size = 2048;
byte[] data = new byte[2048];
while (true)  
{
size = s.Read(data, 0, data.Length);
if (size > 0)  
{
streamWriter.Write(data, 0, size);
}  
else  
{
break;
}
}
streamWriter.Close();
}
}
s.Close();
}

#2


15M数据的释放,3秒钟,你嫌慢。那么先要给出一个数值,你认为应该多少秒?这种目标设定的依据是什么?

如果有依据,才能进一步解决。否则就是空想。

#3


引用 2 楼 sp1234 的回复:
15M数据的释放,3秒钟,你嫌慢。那么先要给出一个数值,你认为应该多少秒?这种目标设定的依据是什么?

如果有依据,才能进一步解决。否则就是空想。

感谢您的指导!
请问正常情况下应该是多大的速度呢?
我在测试时,从客户端开始发一个指令开始,服务器收到指令,开始打开数据库,选择7万多条数据,FIIL到DATASET,共15MB左右,然后压缩,压缩后的数据为1.6MB左右。
压缩后的数据传输到客户端,再解压缩成15MB的数据,展示在客户端。总共时间花费8500左右毫秒。
我并没有一个正常的标准,请问正常的标准又是多少呢?

当然,这只是在测试。实际应用时可以只处理100条数据,然后以分页的方式展示。但是,通讯组件达到什么样的速度才是满足要求的呢?

#4


对,实际应用可以借助WINFORM下的分页控件,将数据进行分页显示。
而对于数量较大的数据,可以只列出ID号。
这样即即使是几万条数据,量也会很小。

#5


该回复于2011-03-05 09:40:24被版主删除

#6


该回复于2011-03-07 14:34:04被版主删除

#7


引用 1 楼 wuyq11 的回复:
public static void DeCompress(string fileName, string dirPath)
        {
            using (Stream source = File.OpenRead(fileName))
            {
                using (Stream destination = new ……


感谢您的回答。
但是你这是基于文件操作的,我需要的是基于流操作的。

#8


15MB数据从开始请求到展示完成,不足9秒...你还嫌慢,人心不足啊...

buffer开大点测试一下,猜测效果不会大...

还有...不要随便GC.Collect();,何况你还放到循环里...随意干预GC通常只会适得其反...

#9


引用 8 楼 vrhero 的回复:
15MB数据从开始请求到展示完成,不足9秒...你还嫌慢,人心不足啊...

buffer开大点测试一下,猜测效果不会大...

还有...不要随便GC.Collect();,何况你还放到循环里...随意干预GC通常只会适得其反...

感谢热心指导!
确实不应在循环中使用GC.Collect();!
15MB的数据,从开始请求到展示完成,用了9秒,这速度真的算是可以吗?
这是在局域网中,而且压缩后的数据只有1.16MB,但是大部份的时间浪费在了压缩和解压缩中。不知道压缩算法能不能再进行优化一下。

#10


哎,楼主找到什么告诉解压的方法了嘛?我也正愁这个呢。。

#1


public static void DeCompress(string fileName, string dirPath)
        {
            using (Stream source = File.OpenRead(fileName))
            {
                using (Stream destination = new MemoryStream())
                {
                    using (GZipStream input = new GZipStream(source, CompressionMode.Decompress, true))
                    {
                        byte[] bytes = new byte[4096];
                        int n;
                        while ((n = input.Read(bytes, 0, bytes.Length)) != 0)
                        {
                            destination.Write(bytes, 0, n);
                        }
                    }
                    destination.Flush();
                    destination.Position = 0;
                    DeSerializeFiles(destination, dirPath);
                }
            }
        }

using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.GZip;
string []FileProperties=new string[2];
FileProperties[0]=strPath; //待解压的文件
FileProperties[1]=strPath+@"\";//解压后放置的目标目录
UnZip(FileProperties);


public void UnZip(string[] args)
{
ZipInputStream s = new ZipInputStream(File.OpenRead(args[0]));
   
ZipEntry theEntry;// = s.GetNextEntry();
while ((theEntry = s.GetNextEntry()) != null)  
{
string directoryName = Path.GetDirectoryName(args[1]);
string fileName = Path.GetFileName(theEntry.Name);
Directory.CreateDirectory(directoryName);
if (fileName != String.Empty)  
{   
//解压文件到指定的目录

FileStream streamWriter = File.Create(args[1]+theEntry.Name);
    
int size = 2048;
byte[] data = new byte[2048];
while (true)  
{
size = s.Read(data, 0, data.Length);
if (size > 0)  
{
streamWriter.Write(data, 0, size);
}  
else  
{
break;
}
}
streamWriter.Close();
}
}
s.Close();
}

#2


15M数据的释放,3秒钟,你嫌慢。那么先要给出一个数值,你认为应该多少秒?这种目标设定的依据是什么?

如果有依据,才能进一步解决。否则就是空想。

#3


引用 2 楼 sp1234 的回复:
15M数据的释放,3秒钟,你嫌慢。那么先要给出一个数值,你认为应该多少秒?这种目标设定的依据是什么?

如果有依据,才能进一步解决。否则就是空想。

感谢您的指导!
请问正常情况下应该是多大的速度呢?
我在测试时,从客户端开始发一个指令开始,服务器收到指令,开始打开数据库,选择7万多条数据,FIIL到DATASET,共15MB左右,然后压缩,压缩后的数据为1.6MB左右。
压缩后的数据传输到客户端,再解压缩成15MB的数据,展示在客户端。总共时间花费8500左右毫秒。
我并没有一个正常的标准,请问正常的标准又是多少呢?

当然,这只是在测试。实际应用时可以只处理100条数据,然后以分页的方式展示。但是,通讯组件达到什么样的速度才是满足要求的呢?

#4


对,实际应用可以借助WINFORM下的分页控件,将数据进行分页显示。
而对于数量较大的数据,可以只列出ID号。
这样即即使是几万条数据,量也会很小。

#5


该回复于2011-03-05 09:40:24被版主删除

#6


该回复于2011-03-07 14:34:04被版主删除

#7


引用 1 楼 wuyq11 的回复:
public static void DeCompress(string fileName, string dirPath)
        {
            using (Stream source = File.OpenRead(fileName))
            {
                using (Stream destination = new ……


感谢您的回答。
但是你这是基于文件操作的,我需要的是基于流操作的。

#8


15MB数据从开始请求到展示完成,不足9秒...你还嫌慢,人心不足啊...

buffer开大点测试一下,猜测效果不会大...

还有...不要随便GC.Collect();,何况你还放到循环里...随意干预GC通常只会适得其反...

#9


引用 8 楼 vrhero 的回复:
15MB数据从开始请求到展示完成,不足9秒...你还嫌慢,人心不足啊...

buffer开大点测试一下,猜测效果不会大...

还有...不要随便GC.Collect();,何况你还放到循环里...随意干预GC通常只会适得其反...

感谢热心指导!
确实不应在循环中使用GC.Collect();!
15MB的数据,从开始请求到展示完成,用了9秒,这速度真的算是可以吗?
这是在局域网中,而且压缩后的数据只有1.16MB,但是大部份的时间浪费在了压缩和解压缩中。不知道压缩算法能不能再进行优化一下。

#10


哎,楼主找到什么告诉解压的方法了嘛?我也正愁这个呢。。