.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();
}
{
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
感谢您的指导!
请问正常情况下应该是多大的速度呢?
我在测试时,从客户端开始发一个指令开始,服务器收到指令,开始打开数据库,选择7万多条数据,FIIL到DATASET,共15MB左右,然后压缩,压缩后的数据为1.6MB左右。
压缩后的数据传输到客户端,再解压缩成15MB的数据,展示在客户端。总共时间花费8500左右毫秒。
我并没有一个正常的标准,请问正常的标准又是多少呢?
当然,这只是在测试。实际应用时可以只处理100条数据,然后以分页的方式展示。但是,通讯组件达到什么样的速度才是满足要求的呢?
#4
对,实际应用可以借助WINFORM下的分页控件,将数据进行分页显示。
而对于数量较大的数据,可以只列出ID号。
这样即即使是几万条数据,量也会很小。
而对于数量较大的数据,可以只列出ID号。
这样即即使是几万条数据,量也会很小。
#5
#6
#7
感谢您的回答。
但是你这是基于文件操作的,我需要的是基于流操作的。
#8
15MB数据从开始请求到展示完成,不足9秒...你还嫌慢,人心不足啊...
buffer开大点测试一下,猜测效果不会大...
还有...不要随便GC.Collect();,何况你还放到循环里...随意干预GC通常只会适得其反...
buffer开大点测试一下,猜测效果不会大...
还有...不要随便GC.Collect();,何况你还放到循环里...随意干预GC通常只会适得其反...
#9
感谢热心指导!
确实不应在循环中使用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();
}
{
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
感谢您的指导!
请问正常情况下应该是多大的速度呢?
我在测试时,从客户端开始发一个指令开始,服务器收到指令,开始打开数据库,选择7万多条数据,FIIL到DATASET,共15MB左右,然后压缩,压缩后的数据为1.6MB左右。
压缩后的数据传输到客户端,再解压缩成15MB的数据,展示在客户端。总共时间花费8500左右毫秒。
我并没有一个正常的标准,请问正常的标准又是多少呢?
当然,这只是在测试。实际应用时可以只处理100条数据,然后以分页的方式展示。但是,通讯组件达到什么样的速度才是满足要求的呢?
#4
对,实际应用可以借助WINFORM下的分页控件,将数据进行分页显示。
而对于数量较大的数据,可以只列出ID号。
这样即即使是几万条数据,量也会很小。
而对于数量较大的数据,可以只列出ID号。
这样即即使是几万条数据,量也会很小。
#5
#6
#7
感谢您的回答。
但是你这是基于文件操作的,我需要的是基于流操作的。
#8
15MB数据从开始请求到展示完成,不足9秒...你还嫌慢,人心不足啊...
buffer开大点测试一下,猜测效果不会大...
还有...不要随便GC.Collect();,何况你还放到循环里...随意干预GC通常只会适得其反...
buffer开大点测试一下,猜测效果不会大...
还有...不要随便GC.Collect();,何况你还放到循环里...随意干预GC通常只会适得其反...
#9
感谢热心指导!
确实不应在循环中使用GC.Collect();!
15MB的数据,从开始请求到展示完成,用了9秒,这速度真的算是可以吗?
这是在局域网中,而且压缩后的数据只有1.16MB,但是大部份的时间浪费在了压缩和解压缩中。不知道压缩算法能不能再进行优化一下。
#10
哎,楼主找到什么告诉解压的方法了嘛?我也正愁这个呢。。