我目前有这个脚本,它压缩字节数组。 但我需要重写它,所以它可以压缩三字节数组[,,]
谢谢!
public static byte[] Compress(byte[] buffer)
{
MemoryStream ms = new MemoryStream();
GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true);
zip.Write(buffer, 0, buffer.Length);
zip.Close();
ms.Position = 0;
MemoryStream outStream = new MemoryStream();
byte[] compressed = new byte[ms.Length];
ms.Read(compressed, 0, compressed.Length);
byte[] gzBuffer = new byte[compressed.Length + 4];
Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
return gzBuffer;
}
public static byte[] Decompress(byte[] gzBuffer)
{
MemoryStream ms = new MemoryStream();
int msgLength = BitConverter.ToInt32(gzBuffer, 0);
ms.Write(gzBuffer, 4, gzBuffer.Length - 4);
byte[] buffer = new byte[msgLength];
ms.Position = 0;
GZipStream zip = new GZipStream(ms, CompressionMode.Decompress);
zip.Read(buffer, 0, buffer.Length);
return buffer;
}
答案 0 :(得分:7)
更新:我重写了代码,现在运行速度更快,代码更清晰。只是用一些随机数据测试它(见本文末尾)。
压缩方法:
public static byte[] Compress(byte[, ,] uncompressed)
{
if (uncompressed == null)
throw new ArgumentNullException("uncompressed",
"The given array is null!");
if (uncompressed.LongLength > (long)int.MaxValue)
throw new ArgumentException("The given array is to large!");
using (MemoryStream ms = new MemoryStream())
using (GZipStream gzs = new GZipStream(ms, CompressionMode.Compress))
{
// Save sizes of the dimensions
for (int dim = 0; dim < 3; dim++)
gzs.Write(BitConverter.GetBytes(
uncompressed.GetLength(dim)), 0, sizeof(int));
// Convert byte[,,] to byte[] by just blockcopying it
// I know, some pointer-magic/unmanaged cast wouldnt
// have to copy it, but its cleaner this way...
byte[] data = new byte[uncompressed.Length];
Buffer.BlockCopy(uncompressed, 0, data, 0, uncompressed.Length);
// Write the data to the stream to compress it
gzs.Write(data, 0, data.Length);
gzs.Close();
// Get the compressed byte array back
return ms.ToArray();
}
}
解压缩方法:
public static byte[, ,] Decompress(byte[] compressed)
{
if (compressed == null)
throw new ArgumentNullException("compressed",
"Data to decompress cant be null!");
using (MemoryStream ms = new MemoryStream(compressed))
using (GZipStream gzs = new GZipStream(ms, CompressionMode.Decompress))
{
// Read the header and restore sizes of dimensions
byte[] dimheader = new byte[sizeof(int) * 3];
gzs.Read(dimheader, 0, dimheader.Length);
int[] dims = new int[3];
for (int j = 0; j < 3; j++)
dims[j] = BitConverter.ToInt32(dimheader, sizeof(int) * j);
// Read the data into a buffer
byte[] data = new byte[dims[0] * dims[1] * dims[2]];
gzs.Read(data, 0, data.Length);
// Copy the buffer to the three-dimensional array
byte[, ,] uncompressed = new byte[dims[0], dims[1], dims[2]];
Buffer.BlockCopy(data, 0, uncompressed, 0, data.Length);
return uncompressed;
}
}
测试代码:
Random rnd = new Random();
// Create a new randomly big array, fill it with random data
byte[, ,] uncomp = new byte[rnd.Next(70, 100),
rnd.Next(70, 100), rnd.Next(70, 100)];
for (int x = 0; x < uncomp.GetLength(0); x++)
for (int y = 0; y < uncomp.GetLength(1); y++)
for (int z = 0; z < uncomp.GetLength(2); z++)
uncomp[x, y, z] = (byte)rnd.Next(30, 35);
// Compress and Uncompress again
Stopwatch compTime = new Stopwatch(), uncompTime = new Stopwatch();
compTime.Start();
byte[] comp = Compress(uncomp);
compTime.Stop();
uncompTime.Start();
byte[, ,] uncompagain = Decompress(comp);
uncompTime.Stop();
// Assert all dimension lengths and contents are equal
for (int j = 0; j < 3; j++)
Debug.Assert(uncomp.GetLength(j) == uncompagain.GetLength(j));
for (int x = 0; x < uncomp.GetLength(0); x++)
for (int y = 0; y < uncomp.GetLength(1); y++)
for (int z = 0; z < uncomp.GetLength(2); z++)
Debug.Assert(uncomp[x, y, z] == uncompagain[x, y, z]);
Console.WriteLine(string.Format("Compression: {0}ms, " +
"Decompression: {1}ms, Ratio: {2}% ({3}/{4} bytes)",
compTime.ElapsedMilliseconds, uncompTime.ElapsedMilliseconds,
(int)((double)comp.LongLength / (double)uncomp.LongLength * 100),
comp.LongLength, uncomp.LongLength));
输出,例如:
Compression: 77ms, Decompression: 23ms, Ratio: 41% (191882/461538 bytes)