C#解压问题

发布于 2024-08-30 14:36:17 字数 1201 浏览 0 评论 0原文

我想在 C# 应用程序中使用 sybase 图像类型列中的一些数据。 Java 使用 java.util.zip 包对数据进行了压缩。我想测试一下我是否可以在 C# 中解压缩数据。所以我编写了一个测试应用程序,将其从数据库中提取出来:

byte[] bytes = (byte[])reader.GetValue(0);  

这给了我一个长度为 2479 的压缩字节[]。
然后我将其传递给看似标准的 C# 解压缩方法:

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;
}  

msgLength 的值为 1503501432,这似乎超出了范围。原始文件应在5K -50k 范围内。无论如何,当我使用该值创建“缓冲区”时,我毫不奇怪地得到了 OutOfMemoryException。 怎么了? Jim

Java的压缩方法如下:

public byte[] compress(byte[] bytes) throws Exception {
    byte[] results = new byte[bytes.length];
    Deflater deflator = new Deflater();
    deflater.setInput(bytes);
    deflater.finish();
    int len = deflater.deflate(results);
    byte[] out = new byte[len];
    for(int i=0; i<len; i++) {
        out[i] = results[i];
    }
    return(out);
}  

Have some data in a sybase image type column that I want to use in a C# app. The data has been compressed by Java using the java.util.zip package. I wanted to test that I could decompress the data in C#. So I wrote a test app that pulls it out of the database:

byte[] bytes = (byte[])reader.GetValue(0);  

This gives me a compressed byte[] of 2479 length.
Then I pass this to a seemingly standard C# decompression method:

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;
}  

The value for msgLength is 1503501432 which seems way out of range. The original document should be in the range of 5K -50k. Anyway when I use that value to create "buffer" not surprisingly I get an OutOfMemoryException.
What is happening?
Jim

The Java compress method is as follows:

public byte[] compress(byte[] bytes) throws Exception {
    byte[] results = new byte[bytes.length];
    Deflater deflator = new Deflater();
    deflater.setInput(bytes);
    deflater.finish();
    int len = deflater.deflate(results);
    byte[] out = new byte[len];
    for(int i=0; i<len; i++) {
        out[i] = results[i];
    }
    return(out);
}  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

许一世地老天荒 2024-09-06 14:36:17

由于我看不到你的 java 代码,我只能猜测你正在将数据压缩到 zip 文件流中。因此,如果您尝试在 C# 中使用 gzip 解压缩来解压缩该流,它显然会失败。您可以将 java 代码更改为 gzip 压缩(示例 此处页面底部),或者使用适当的库(例如 SharpZipLib< /a>)。

更新

现在,我看到您正在使用 deflate 在 java 中进行压缩。所以,显然你必须在 c# 中使用相同的算法:System.IO.Compression.DeflateStream

public static byte[] Decompress(byte[] buffer)
{
    using (MemoryStream ms = new MemoryStream(buffer))
    using (Stream zipStream = new DeflateStream(ms, 
                          CompressionMode.Decompress, true))
    {
        int initialBufferLength = buffer.Length * 2;

        byte[] buffer = new byte[initialBufferLength];
        bool finishedExactly = false;
        int read = 0;
        int chunk;

        while (!finishedExactly && 
              (chunk = zipStream.Read(buffer, read, buffer.Length - read)) > 0)
        {
            read += chunk;

            if (read == buffer.Length)
            {
                int nextByte = zipStream.ReadByte();

                // End of Stream?
                if (nextByte == -1)
                {
                    finishedExactly = true;
                }
                else
                {
                    byte[] newBuffer = new byte[buffer.Length * 2];
                    Array.Copy(buffer, newBuffer, buffer.Length);
                    newBuffer[read] = (byte)nextByte;
                    buffer = newBuffer;
                    read++;
                }
            }
        }
        if (!finishedExactly)
        {
            byte[] final = new byte[read];
            Array.Copy(buffer, final, read);
            buffer = final;
        }
    }

    return buffer;
}  

As I cant see your java code, I can only guess you are compressing your data to a zip file stream. Therefore it will obviously fail if you are trying to decompress that stream with a gzip decompression in c#. Either you change your java code to a gzip compression (Example here at the bottom of the page), or you decompress the zip file stream in c# with an appropriate library (e.g. SharpZipLib).

Update

Ok now, I see you are using deflate for the compression in java. So, obviously you have to use the same algorithm in c#: System.IO.Compression.DeflateStream

public static byte[] Decompress(byte[] buffer)
{
    using (MemoryStream ms = new MemoryStream(buffer))
    using (Stream zipStream = new DeflateStream(ms, 
                          CompressionMode.Decompress, true))
    {
        int initialBufferLength = buffer.Length * 2;

        byte[] buffer = new byte[initialBufferLength];
        bool finishedExactly = false;
        int read = 0;
        int chunk;

        while (!finishedExactly && 
              (chunk = zipStream.Read(buffer, read, buffer.Length - read)) > 0)
        {
            read += chunk;

            if (read == buffer.Length)
            {
                int nextByte = zipStream.ReadByte();

                // End of Stream?
                if (nextByte == -1)
                {
                    finishedExactly = true;
                }
                else
                {
                    byte[] newBuffer = new byte[buffer.Length * 2];
                    Array.Copy(buffer, newBuffer, buffer.Length);
                    newBuffer[read] = (byte)nextByte;
                    buffer = newBuffer;
                    read++;
                }
            }
        }
        if (!finishedExactly)
        {
            byte[] final = new byte[read];
            Array.Copy(buffer, final, read);
            buffer = final;
        }
    }

    return buffer;
}  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文