如果您不知道事先要分配多少字节,如何初始化字节缓冲区?图书馆已知数量未知数量例优化

2022-09-02 20:53:42

是这样的:

ByteBuffer buf = ByteBuffer.allocate(1000);

...初始化 ?ByteBuffer

如果我不知道我需要分配多少字节怎么办..?

编辑:更多详情:

我正在将一种图像文件格式转换为TIFF文件。问题是起始文件格式可以是任何大小,但我需要将TIFF中的数据写入小字节序。因此,我正在阅读我最终要打印到TIFF文件的东西,首先将其放入ByteBuffer中,这样我就可以将所有内容放入Little Endian中,然后我将它写入outfile。我想,由于我知道 IFD 的长度,标头有多长,并且我可能可以计算出每个图像平面中有多少字节,因此在整个过程中,我只能使用多个 ByteBuffer。


答案 1

要使用的位置类型通常是否则将使用字节数组(也具有固定大小)的放置类型。对于同步 I/O,您通常使用字节数组,而对于异步 I/O,则使用字节缓冲器。ByteBuffer

如果需要使用 读取未知数量的数据,请考虑对缓冲区使用循环,并在读取数据时将数据追加到 ByteArrayOutputStream。完成后,调用以获取最终的字节数组。ByteBuffertoByteArray()

任何时候,当您不能绝对确定给定输入的大小(或最大大小)时,在循环中读取(可能使用 ,但除此之外,只是在读取数据时将数据作为流处理)是处理它的唯一方法。如果没有某种循环,任何剩余的数据当然都会丢失。ByteArrayOutputStream

例如:

final byte[] buf = new byte[4096];
int numRead;

// Use try-with-resources to auto-close streams.
try(
  final FileInputStream fis = new FileInputStream(...);
  final ByteArrayOutputStream baos = new ByteArrayOutputStream()
) {
  while ((numRead = fis.read(buf)) > 0) {
    baos.write(buf, 0, numRead);
  }

  final byte[] allBytes = baos.toByteArray();

  // Do something with the data.
}
catch( final Exception e ) {
  // Do something on failure...
}

如果你想写Java或其他不是原始字节的东西,你可以把你的包装在DataOutputStream中:intByteArrayOutputStream

ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);

while (thereAreMoreIntsFromSomewhere()) {
    int someInt = getIntFromSomewhere();
    dos.writeInt(someInt);
}

byte[] allBytes = baos.toByteArray();    

答案 2

取决于。

图书馆

对于大多数问题域来说,转换文件格式往往是一个已解决的问题。例如:

  • 蜡染可以在各种图像格式(包括TIFF)之间进行转码。
  • Apache POI可以在办公电子表格格式之间进行转换。
  • Flexmark可以从Markdown生成HTML。

这个清单很长。第一个问题应该是,“哪个可以完成这项任务?如果性能是一个考虑因素,那么你的时间可能更好地花在优化现有软件包上以满足您的需求,而不是编写另一个工具。(作为奖励,其他人可以从集中工作中受益。


已知数量

  • 正在读取文件?分配字节。file.size()
  • 复制字符串?分配字节。string.length()
  • 复制 TCP 数据包?例如,分配 1500 个字节。

未知数量

当字节数确实未知时,您可以执行以下操作:

  • 做个猜。
  • 分析示例数据集以进行缓冲;使用平均长度。

除非另有说明,否则 Java 使用初始缓冲区大小来容纳 16 个字符。填充 16 个字符后,将分配一个新的、更长的数组,然后复制原始的 16 个字符。如果 初始大小为 1024 个字符,则重新分配不会那么早或那么频繁地发生。StringBufferStringBuffer

优化

无论哪种方式,这都可能是过早的优化。通常,当您想要减少执行的内部存储器重新分配的数量时,会分配一定数量的字节。

这不太可能成为应用程序的瓶颈。