java 包装 GZIPOutputStream & ByteArrayOutputStream 一起 - 我做错了什么?

发布于 2024-11-28 01:55:06 字数 3324 浏览 3 评论 0原文

Main.java

import java.io.IOException;

public class Main
{

    private final CompressedOutputStream    m_cos;

    public static void main(String[] args)
    {
        try
        {
            final Main m = new Main(new CompressedOutputStream());
            m.run();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public Main(final CompressedOutputStream cos)
    {
        this.m_cos = cos;
    }

    private void trace(final String format, Object... args)
    {
        final String output = String.format(format, args);
        System.out.println(output);
    }

    public void run()
    {
        this.first_write();
        this.second_write();
        this.trace("CRC32 of data is %x", this.m_cos.get_crc32());
    }

    private void add_data(final byte[] data)
    {
        try
        {
            this.m_cos.write(data); // STEPPING INTO THIS IN DEBUG DOESN'T LEAD ANYWHERE!
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public void first_write()
    {
        final String[] text_lines = new String[] { "Hello world!",
                "My name is Joe.", "Nice to meet.", "Where are you from?",
                "I'm from Congo" };

        for (final String text_line : text_lines)
        {
            final byte[] data = text_line.getBytes();
            this.add_data(data);
        }

        final byte[] compressed_data = this.m_cos.get_compressed_data();
        trace("Compressed data length (so far) is %d bytes",
                compressed_data.length);
    }

    public void second_write()
    {
        final byte[] additional_data = new byte[] { 0x00, 0x01, 0x02, 0x03,
                0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
        this.add_data(additional_data);

        final byte[] total_compressed_data = this.m_cos.get_compressed_data();
        trace("Total compressed data length is %d bytes",
                total_compressed_data.length);
    }
}

CompressedOutputStream.java

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.GZIPOutputStream;

public class CompressedOutputStream extends GZIPOutputStream
{

    private final ByteArrayOutputStream m_out;

    public CompressedOutputStream() throws IOException
    {
        this(32);
    }

    public CompressedOutputStream(int size) throws IOException
    {
        super(new ByteArrayOutputStream(size), size);
        this.m_out = (ByteArrayOutputStream) this.out;
        this.def.setLevel(Deflater.BEST_COMPRESSION);
    }

    public long get_crc32()
    {
        return this.crc.getValue();
    }

    public byte[] get_compressed_data()
    {
        return this.m_out.toByteArray();
    }
}

所以我有这段代码尝试将 GZIPOutputStream 与 ByteArrayOutputStream 结合起来。

由于某种原因,我得到的只是相同的 10 个字节。
得到这个输出:

压缩数据长度(到目前为止)为 10 字节
压缩数据总量 长度为10字节
数据的CRC32为4550d94d

似乎调用 write() 最终得到一个抽象函数,即它没有到达任何地方,也没有写入任何内容。
我希望它能够被即时写入、压缩,并且能够在以后获取压缩的字节。

我在这里缺少什么?看似微不足道,但事实并非如此。

编辑#1:我的最终目标
只是为了澄清:最后我需要的是一个内存缓冲区,我将按块而不是按顺序写入,并且在某个时刻,当它达到 X 字节时,我将能够获取这些压缩的& ;校验和,字节(将它们写入某处,而不是标准 Java 流)。

Main.java

import java.io.IOException;

public class Main
{

    private final CompressedOutputStream    m_cos;

    public static void main(String[] args)
    {
        try
        {
            final Main m = new Main(new CompressedOutputStream());
            m.run();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public Main(final CompressedOutputStream cos)
    {
        this.m_cos = cos;
    }

    private void trace(final String format, Object... args)
    {
        final String output = String.format(format, args);
        System.out.println(output);
    }

    public void run()
    {
        this.first_write();
        this.second_write();
        this.trace("CRC32 of data is %x", this.m_cos.get_crc32());
    }

    private void add_data(final byte[] data)
    {
        try
        {
            this.m_cos.write(data); // STEPPING INTO THIS IN DEBUG DOESN'T LEAD ANYWHERE!
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public void first_write()
    {
        final String[] text_lines = new String[] { "Hello world!",
                "My name is Joe.", "Nice to meet.", "Where are you from?",
                "I'm from Congo" };

        for (final String text_line : text_lines)
        {
            final byte[] data = text_line.getBytes();
            this.add_data(data);
        }

        final byte[] compressed_data = this.m_cos.get_compressed_data();
        trace("Compressed data length (so far) is %d bytes",
                compressed_data.length);
    }

    public void second_write()
    {
        final byte[] additional_data = new byte[] { 0x00, 0x01, 0x02, 0x03,
                0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
        this.add_data(additional_data);

        final byte[] total_compressed_data = this.m_cos.get_compressed_data();
        trace("Total compressed data length is %d bytes",
                total_compressed_data.length);
    }
}

CompressedOutputStream.java

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.GZIPOutputStream;

public class CompressedOutputStream extends GZIPOutputStream
{

    private final ByteArrayOutputStream m_out;

    public CompressedOutputStream() throws IOException
    {
        this(32);
    }

    public CompressedOutputStream(int size) throws IOException
    {
        super(new ByteArrayOutputStream(size), size);
        this.m_out = (ByteArrayOutputStream) this.out;
        this.def.setLevel(Deflater.BEST_COMPRESSION);
    }

    public long get_crc32()
    {
        return this.crc.getValue();
    }

    public byte[] get_compressed_data()
    {
        return this.m_out.toByteArray();
    }
}

So I have this code which tries to combine GZIPOutputStream with ByteArrayOutputStream.

For some reason all I'm getting is the same 10 bytes.
Getting this output:

Compressed data length (so far) is 10 bytes
Total compressed data
length is 10 bytes
CRC32 of data is 4550d94d

It seems like calling to write() ends-up with an abstractive function, i.e it doesn't get anywhere, nor anything is written.
I want it to be written, compressed, on the fly, and be able to take the compressed bytes at later time.

What am I missing here? Seems trivial but no so.

Edit #1: My final goal
Just to clarify: At the end all I need is an in-memory buffer to which I will write, in chunks and not in a sequence, and at some point when it reaches X bytes I'll be able to take these, compressed & checksum'ed, bytes (to write them somewhere, not a standard Java stream).

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

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

发布评论

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

评论(1

对你再特殊 2024-12-05 01:55:06

GZIPOutputStream 在将数据传递到下一个之前会进行一些内部缓冲
链中的流(在本例中为 ByteArrayOutputStream)。因此,您必须先 close() 流,然后才能读回字节。例如,我对 secondary_write() 进行了以下修改:

this.m_cos.close();
final byte[] total_compressed_data = this.m_cos.get_compressed_data();
trace("Total compressed data length is %d bytes", total_compressed_data.length);

这给了我输出:

压缩数据长度(到目前为止)为10字节
压缩数据总长度为98字节
数据的CRC32为4550d94d

如果您无法关闭流,可能有一种方法可以在不关闭的情况下强制刷新内部缓冲区。 (虽然我尝试过,flush()本身并没有这样做)。

GZIPOutputStream does some internal buffering before it passes the data along to the next
stream in the chain (in this case the ByteArrayOutputStream). Thus you have to close() the stream before you can read the bytes back out. For example, I made the following modification to second_write():

this.m_cos.close();
final byte[] total_compressed_data = this.m_cos.get_compressed_data();
trace("Total compressed data length is %d bytes", total_compressed_data.length);

This gave me the output:

Compressed data length (so far) is 10 bytes
Total compressed data length is 98 bytes
CRC32 of data is 4550d94d

If you can't afford to close the stream, there might be a way to forcibly flush the internal buffer without closing. (flush() itself doesn't do that though, I tried).

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