Стратегия BufferedOutputStream для Java

Вы можете указать конструктору BufferedOutputStream параметр int для размера буфера. В моем сценарии у меня есть один процесс записи на диск и процесс чтения с диска. Наличие буфера по умолчанию в 8192 байта вызывает высокую фрагментацию больших файлов.

Теперь мне было интересно, смогу ли я уменьшить фрагментацию, если подниму размер буфера до 1 Мб.

Я думаю, это должно сработать. Но уважает ли BufferedOutputStream мой буфер, если я всегда вызываю BufferedOutputStream.write(smallBuffer,0,i); // i being smaller than 8192

я маленький, потому что ловлю маленькие пакеты (8192 байта) по сети. Но я хочу, чтобы BufferedOutputStream действительно много буферизировал, а не решил сбросить раньше?

Является ли BufferedOutputStream достаточно "глупым", чтобы дождаться заполнения буфера или вызова flush(). Или у него установлен какой-то механизм промывки, основанный на времени?


person Franz Kafka    schedule 08.06.2011    source источник


Ответы (2)


BufferedOutputStream не использует какой-либо алгоритм, основанный на времени, или другую статистику для внутреннего вызова сброса. Он будет сбрасываться, как только буфер будет заполнен, или вы очистите его явно (или до того, как буферизованный поток будет закрыт).

Другими словами: больший размер буфера уменьшит фрагментацию для вашего варианта использования.

person Sebastian Zarnekow    schedule 08.06.2011

Согласно Javadoc:

Обычно этот метод сохраняет байты из заданного массива в буфер этого потока, при необходимости сбрасывая буфер в базовый выходной поток.

http://download.oracle.com/javase/6/docs/api/java/io/BufferedOutputStream.html

А если посмотреть исходники (реализация Sun):

public synchronized void write(byte b[], int off, int len) throws IOException {
    //flushBuffer() if necessary
    System.arraycopy(b, off, buf, count, len);
    count += len;
}

flushBuffer() возникает только в том случае, если фрагмент данных больше, чем весь буфер, или если добавление его в буфер вызовет переполнение.

Итак, чтобы ответить быстро: да. И неявного flush() нет, приходится вызывать вручную, если нужно, а буфер еще не заполнен.

person Tomasz Nurkiewicz    schedule 08.06.2011