Некоторые мысли:
Нельзя сказать, что это - решенный вопрос, или что не будет обратной реакции через 3-5 лет (поскольку всегда существует). Однако тенденцию к FP имеет заслугу и стоит наблюдать.
Зависит.
Преобразование форматов файлов обычно решенная проблема для большинства проблемных областей. Например:
file.size ()
байт. string.length ()
байт. Если количество байтов действительно неизвестно, вы можете сделать несколько вещей:
Java StringBuffer
, если не указано иное, использует начальный размер буфера для хранения 16 символов. После заполнения 16 символов выделяется новый, более длинный массив, а затем скопированы исходные 16 символов. Если бы StringBuffer
имел начальный размер 1024 символа, то перераспределение не происходило бы так рано или так часто.
В любом случае, это, вероятно, преждевременная оптимизация. Обычно вы выделяете определенное количество байтов, если хотите уменьшить количество выполняемых перераспределений внутренней памяти.
Маловероятно, что это будет узким местом приложения.
Типы мест, в которых вы бы использовали ByteBuffer
, обычно являются типами мест, в которых вы в противном случае использовали бы массив байтов (который также имеет фиксированный размер). При синхронном вводе-выводе вы часто используете байтовые массивы, при асинхронном вводе-выводе вместо них используются 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
s или другие вещи, не являющиеся исходными байтами, вы можете обернуть свой ByteArrayOutputStream
в DataOutputStream
:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
while (thereAreMoreIntsFromSomewhere()) {
int someInt = getIntFromSomewhere();
dos.writeInt(someInt);
}
byte[] allBytes = baos.toByteArray();
Идея в том, что это всего лишь буфер - не все данные. Это временное место для хранения данных, когда вы читаете кусок, обрабатываете его (возможно, записываете в другое место). Итак, выделите себе достаточно большой «кусок», и обычно это не будет проблемой.
Какую проблему вы ожидаете?