Как определить размер буфера для метода записи BufferedOutputStream - PullRequest
2 голосов
/ 03 апреля 2012

Я пытаюсь скопировать файл, используя следующий код:

1:

        int data=0;
        byte[] buffer = new byte[4096];
        while((data = bufferedInputStream.read())!=-1){
            bufferedOutputStream.write(data);
        }

2:

        byte[] buffer = new byte[4096];
        while(bufferedInputStream.read(buffer)!=-1){
            bufferedOutputStream.write(buffer);
        }

Фактический размер файла 3892028 байт(на окнах).Файл будет загружен пользователем thro struts2 fileupload.Размер загружаемого файла точно такой же, как у Windows.Когда я пытаюсь скопировать загруженный файл из временной папки, размер копируемого файла изменяется, а время, которое требуется, также различается (это незначительно).Пожалуйста, найдите показания ниже.

Without using buffer(Code 1)
Time taken 77
3892028
3891200

Buffer size 1024(Code 2)
Time taken 17
3892028
3891200

Buffer size 4096(Code 2)
Time taken 18
3892028
3891200

Buffer size 10240(Code 2)
Time taken 14
3892028
3901440

Buffer size 102400(Code 2)
Time taken 9
3892028
3993600

Если я увеличу размер буфера еще больше, затраченное время увеличится, опять же, оно будет незначительным.Итак, мои вопросы:

  1. Почему размер файла изменяется?
  2. Есть ли какие-либо тонкие последствия из-за этого изменения размера?
  3. Каков наилучший способ реализовать эту функцию (копирование файла)?

Я не знаю, что происходит ниже?Спасибо за любое предложение. Редактировать: У меня есть вызовы методов flush () и close (). Примечание: Я сократил свой код, чтобы сделать его проще.

Ответы [ 2 ]

10 голосов
/ 03 апреля 2012

Проблема в том, что BufferedInputStream.read(byte[]) читает как можно больше в буфер. Таким образом, если поток содержит только 1 байт, будет заполнен только первый байт массива байтов. Однако BufferedInputStream.write(byte[]) записывает все заданных байтов в поток, что означает, что он все равно будет записывать полные 4096 байтов, содержащие 1 байт из текущей итерации и 4095 оставшихся байтов из предыдущей итерации.

Что вам нужно сделать, это сохранить количество прочитанных байтов, а затем записать такое же количество.

Пример:

int lastReadCnt = 0;
byte[] buffer = new byte[4096];
while((lastReadCnt = bufferedInputStream.read(buffer))!=-1){
    bufferedOutputStream.write(buffer, 0, lastReadCnt);
}

Ссылка:

5 голосов
/ 03 апреля 2012
  1. Почему размер файла меняется?
Вы забыли `flush ()` (и `close ()`): bufferedOutputStream.flush ()

Также вы должны передать количество прочитанных байтов в write метод:

bufferedOutputStream.write(data, 0, bytesRead);
  1. Как лучше всего выполнить эту функцию (копирование файла)?

Оба из IO.

...