Bob*_*y Z 35 c# compression zip image bitmap
我需要一种在.net中压缩图像的方法,所以我研究了使用.net GZipStream类(或DeflateStream).然而,我发现解压缩并不总是成功,有时图像会很好地解压缩,而有时我会得到GDI +错误,表明某些内容已损坏.
在调查问题后,我发现解压缩没有回复它压缩的所有字节.因此,如果我压缩2257974字节,我有时会回来2257870字节(实数).
最有趣的是,有时它会起作用.所以我创建了这个只压缩10个字节的小测试方法,现在我根本没有回复任何东西.
我用压缩类GZipStream和DeflateStream尝试了它,我仔细检查了我的代码是否存在可能的错误.我甚至尝试将流定位到0并冲洗所有流但没有运气.
这是我的代码:
public static void TestCompression()
{
byte[] test = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
byte[] result = Decompress(Compress(test));
// This will fail, result.Length is 0
Debug.Assert(result.Length == test.Length);
}
public static byte[] Compress(byte[] data)
{
var compressedStream = new MemoryStream();
var zipStream = new GZipStream(compressedStream, CompressionMode.Compress);
zipStream.Write(data, 0, data.Length);
return compressedStream.ToArray();
}
public static byte[] Decompress(byte[] data)
{
var compressedStream = new MemoryStream(data);
var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress);
var resultStream = new MemoryStream();
var buffer = new byte[4096];
int read;
while ((read = zipStream.Read(buffer, 0, buffer.Length)) > 0) {
resultStream.Write(buffer, 0, read);
}
return resultStream.ToArray();
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ell 49
您需要Close()在ZipStream将所有要压缩后的数据; 它在内部(即使你Flush())保留了需要写入的未写字节缓冲区.
更一般地说,Stream是IDisposable,所以你也应该是using每一个......(是的,我知道这MemoryStream不会丢失任何数据,但是如果你没有养成这种习惯,它会咬你的其他Streams).
public static byte[] Compress(byte[] data)
{
using (var compressedStream = new MemoryStream())
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
{
zipStream.Write(data, 0, data.Length);
zipStream.Close();
return compressedStream.ToArray();
}
}
public static byte[] Decompress(byte[] data)
{
using(var compressedStream = new MemoryStream(data))
using(var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
using (var resultStream = new MemoryStream())
{ ... }
}
Run Code Online (Sandbox Code Playgroud)
[编辑:更新评论]不是这样的using事情MemoryStream- 这总是一个有趣的,在围栏的两边都有很多选票:但是极端......
(修辞 - 我们都知道答案......)如何MemoryStream实施?它是一个byte [](由.NET拥有)?它是一个内存映射文件(由操作系统拥有)?
你不是using这样的原因是因为你让内部实现细节的知识改变了你对公共API进行编码的方式 - 即你刚刚违反了封装法则.公共API说:我是IDisposable; 你欠我的; 因此,Dispose()当你经历时,这是我的工作.
| 归档时间: |
|
| 查看次数: |
16678 次 |
| 最近记录: |