这是:
ByteBuffer buf = ByteBuffer.allocate(1000);
...初始化ByteBuffer
的唯一方法?
如果我不知道需要分配多少字节怎么办?
修改:更多详情:
我正在将一种图像文件格式转换为TIFF文件。问题是起始文件格式可以是任何大小,但我需要将TIFF中的数据写入小端。所以我正在阅读我最终将打印到TIFF文件的内容首先打印到ByteBuffer中,这样我就可以将所有内容放入Little Endian中,然后我将其写入outfile。我想因为我知道IFD有多长,标题是,我可以计算出每个图像平面中有多少字节,我可以在整个过程中使用多个ByteBuffers。
答案 0 :(得分:11)
您将使用ByteBuffer
的地方类型通常是您将使用字节数组(也具有固定大小)的地方类型。对于同步I / O,您经常使用字节数组,使用异步I / O,而是使用ByteBuffers。
如果您需要使用ByteBuffer
读取未知数量的数据,请考虑在缓冲区中使用循环,并在阅读时将数据附加到ByteArrayOutputStream 。完成后,调用toByteArray()
以获取最终的字节数组。
任何时候当你不完全确定给定输入的大小(或最大大小)时,读取循环(可能使用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 int
或其他不是原始字节的东西,你可以将ByteArrayOutputStream
包裹在DataOutputStream
中:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
while (thereAreMoreIntsFromSomewhere()) {
int someInt = getIntFromSomewhere();
dos.writeInt(someInt);
}
byte[] allBytes = baos.toByteArray();
答案 1 :(得分:7)
取决于
转换文件格式往往是大多数问题域的解决问题。例如:
列表很长。第一个问题应该是,“library可以完成这项任务?”如果考虑性能,那么与编写其他工具相比,优化现有软件包以满足您的需求可能会花费更多时间。 (作为奖励,其他人可以从集中工作中受益。)
file.size()
个字节。string.length()
个字节。当字节数真的未知时,你可以做一些事情:
除非另有说明,否则Java StringBuffer
使用初始缓冲区大小来保存16个字符。填充16个字符后,将分配一个新的较长的数组,然后复制原始的16个字符。如果StringBuffer
的初始大小为1024个字符,则重新分配不会像早期或经常那样发生。
无论哪种方式,这可能是一个不成熟的优化。通常,当您想减少执行的内部内存重新分配的数量时,您将分配一定数量的字节。
这不太可能是应用程序的瓶颈。
答案 2 :(得分:4)
这个想法是它只是一个缓冲区 - 而不是整个数据。当你读取一个块,处理它(可能在其他地方写它)时,它是数据的临时休息点。所以,给自己分配一个足够大的“块”,通常不会有问题。
您期待什么问题?