我有一个库,可以生成PDF文档并将其写入OutputStream
。 OutputStream
传递给PDF库。我需要将结果数据存储在 List<Byte[]>
List<byte[]>
中,每个条目的固定长度为255个字节。 (我无法改变有关此要求的任何内容,请参阅评论中的更多内容。)
现在最简单的解决方案是使用ByteArrayOutputStream
并将生成的字节数组写入(并反汇编)到字节数组列表中。
但我想要一个更有效的解决方案,需要更少的内存。我希望输出流直接生成字节数组列表。
我的解决方案是扩展OutputStream
,覆盖write()
并将数据直接写入List<byte[]>
。
这需要一些努力(例如跟踪已经收到的字节数),因此我想知道,如果使用其他可用的OutputStream
实现有更简单的解决方案。
E.g。我想过以某种方式使用BufferedOutputStream
,但我认为这不会起作用。基本思想是实现另一个OutputStream
,将其传递给具有255字节容量的BufferedOutputStream
并写入一个新的块条目,每次BufferdOutputStream
刷新其缓冲区时它都已满。我认为这不起作用,因为BufferedOutputStream
如果一次写入太多字节就不再使用它的缓冲区(据我所知,它的源代码)。
答案 0 :(得分:0)
这是我在问题中提出的快速实施方式。但是,它没有经过测试。但是在我的代码中使用它之前我必须做一些具体的更改,并且在应用这些更改之前我会分享它。
public class ByteArrayListGeneratingOutputStream extends OutputStream
{
private byte[] buf;
private int off = 0;
private int size;
private List<byte[]> result = new ArrayList<byte[]>();
public ByteArrayListGeneratingOutputStream(int size)
{
this.size = size;
buf = new byte[size];
}
public List<byte[]> getResult()
{
return result;
}
@Override
public void write(int b) throws IOException
{
allocateBufferIfNeeded();
buf[off++] = (byte) b;
flushBufferIfNeeded();
}
@Override
public void write(byte buf[], int off, int len) throws IOException
{
if ((off < 0) || (off > buf.length) || (len < 0) || ((off + len) > buf.length) || ((off + len) < 0))
{
throw new IndexOutOfBoundsException();
}
while (len > 0)
{
allocateBufferIfNeeded();
int effectiveLen = Math.min(len, size - this.off);
System.arraycopy(buf, off, this.buf, this.off, effectiveLen);
this.off += effectiveLen;
off += effectiveLen;
len -= effectiveLen;
flushBufferIfNeeded();
}
}
private void flushBufferIfNeeded() throws IOException
{
if (off == size)
{
flush();
}
}
private void allocateBufferIfNeeded()
{
if (buf == null)
{
buf = new byte[size];
off = 0;
}
}
@Override
public void flush() throws IOException
{
if (off > 0)
{
result.add(buf);
off = 0;
buf = null;
}
}
@Override
public void close() throws IOException
{
flush();
}
}