powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / BufferedReader и размер буфера
18 сообщений из 18, страница 1 из 1
BufferedReader и размер буфера
    #38322008
Gustly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день. Имеется код. На вход ZIP архив из базы, на выход разархивированные файлы.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
ZipInputStream zip = new ZipInputStream(blob.getBinaryStream());
InputStreamReader reader = new InputStreamReader(zip);
BufferedReader r = new BufferedReader(reader);

File file_out = new File("C:\\" + e.getName());
OutputStream os = new FileOutputStream(file_out);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));

char[] bytes = new char[[color=red]1024*1024[/color]];

while ((cnt = r.read(bytes))!= -1)
writer.write(bytes);


При данном размере буфера размер (и содержимое) выходного файла отличается (стал больше) от файла в архиве новые 161 480 704 байт против 160 776 000 байт старых.
Если размер буфера уменьшить до 256 например, то размеры совпадают, но конец файла чуть-чуть искажается.
При размере буфера 64 файлы совпадают.
Вопрос, почему?
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322019
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во-первых Reader и Writer предназначены для текстовых данных. Для того чтобы вычитать двоичный файл из архива и сохранить в файл на диске, они не нужны. Тем более вы не знаете кодировку текстового файла (UTF8, CP1251, etc) и пытаетесь использовать текущую.
Во-вторых когда используется Buffered Reader/Writer/Stream нет необходимости добавлять свой буфер char[] bytes = new char[n];
Можно читать по одному символу или байту. Buffered класс уже реализует такой буфер внутри.
И в-третих переменная cnt содержит значение, которое вам нужно использовать для записи, а вы его игнорируете.
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322080
Gustly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczВо-первых Reader и Writer предназначены для текстовых данных. Для того чтобы вычитать двоичный файл из архива и сохранить в файл на диске, они не нужны
Я знаю, что там текстовые файлы.

BlazkowiczТем более вы не знаете кодировку текстового файла (UTF8, CP1251, etc) и пытаетесь использовать текущую.
Очень долго мучался с кодировкой, особенно не хотелись создаваться файлы с русскими именами. Сделал System.setProperty("file.encoding", "Cp1251"); и стало хорошо везде.

BlazkowiczВо-вторых когда используется Buffered Reader/Writer/Stream нет необходимости добавлять свой буфер char[] bytes = new char[n];
Можно читать по одному символу или байту. Buffered класс уже реализует такой буфер внутри.
А зачем же тогда метод read(char[] cbuf) ?

BlazkowiczИ в-третих переменная cnt содержит значение, которое вам нужно использовать для записи, а вы его игнорируете.
В cnt содержится значение для записи, если использовать read без входных параметров. Если с входными там количество считанных байт, исли оно =-1, то выход из цикла.\


Вы говорите, read лучше чем read(char[]) ? Но он вроде дольше отрабатывает. Даже когда я уменьшаю буфер свой до 64, оно дольше идет примерно на 50% (15 сек против 10 сек, но это файлы еще маленькие), хотя по-разному бывает.
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322114
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GustlyЯ знаю, что там текстовые файлы.
Тогда стоило писать вот так:
Код: java
1.
2.
InputStreamReader reader = new InputStreamReader(zip, MY_TEXT_FILES_ENCODING);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, MY_TEXT_FILES_ENCODING));



GustlySystem.setProperty("file.encoding", "Cp1251");
И не дай бог нужно что-то кроме латиницы и кириллицы? А вдруг кто-то в этой же JVM надется на UTF-8?
Так вы текст анализируете ещё параллельно или нет? Потому что код, который я вижу тупо заменяется одной строкой:
Код: java
1.
IOUtils.copy( new ZipInputStream(blob.getBinaryStream()), new FileOutputStream(new File("C:\\" + e.getName())));


И никакого гемороя с кодировками и буферами.

GustlyА зачем же тогда метод read(char[] cbuf) ?
Это метод класса Reader. Reader может быть не буферизированым.

BlazkowiczИ в-третих переменная cnt содержит значение, которое вам нужно использовать для записи, а вы его игнорируете.
В cnt содержится значение для записи, если использовать read без входных параметров. Если с входными там количество считанных байт, исли оно =-1, то выход из цикла.
Правильно. И каждый раз когда cnt < bytes.length() вы записываете больше символов чем прочитали.

GustlyВы говорите, read лучше чем read(char[]) ?
Нет. Я так не говорил. Вы меня перевираете. Я говорю что буфер уже есть в BufferedReader и в BufferedWriter. Поэтому ваш собственный уже не нужен.

GustlyНо он вроде дольше отрабатывает. Даже когда я уменьшаю буфер свой до 64, оно дольше идет примерно на 50% (15 сек против 10 сек, но это файлы еще маленькие), хотя по-разному бывает.
Это ещё раз показывает что JavaDoc ни одного из используемых классов вы не открывали.
Сделайте так:
Код: java
1.
2.
BufferedReader r = new BufferedReader(reader, 1024*1024);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os), 1024*1024);


И производительность уравняется.
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322145
Gustly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А как на счет изначального вопроса? Почему файл коверкается?
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322149
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GustlyА как на счет изначального вопроса? Почему файл коверкается?
Потому что вы читаете cnt символов, а записываете 1024*1024. cnt != 1024*1024 и это не только признак конца файла.
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322154
Gustly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IOUtils у меня нету такого пакета. Видимо его отдельно надо ставить, а в библиотеки оракла не хотелось бы чего стороннего пихать, да и не пробовал ни разу.
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322163
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/1.4/org/apache/commons/io/IOUtils.java#IOUtils.copyLarge(java.io.InputStream,java.io.OutputStream)
Можете скопипастить себе. Там ничего военного:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
public static long copyLarge(InputStream input, OutputStream output) throws IOException {

        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        long count = 0;
        int n = 0;

        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
        }
        return count;
}
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322177
Gustly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

В этом примере тоже массив для буфера используется, но нету BufferedReader. Как лучше-то? Как пользоваться read() из BufferedReader. Он читает инт, а когда пишешь его он пишет символы @.
Код: java
1.
2.
while ((cnt = r.read(bytes))!= -1)
writer.write(cnt);
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322181
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gustly
Код: java
1.
2.
while ((cnt = r.read(bytes))!= -1)
writer.write(cnt);


Для вас это вообще непонятный набор букв и вы его переставляете как вам нравится, пока что-то не получится?
bytes - данные
cnt - количество прочитаных данных
writer.write(cnt) - пишем количество прочитаных данных как текст
А ожидаем почему-то данные, которые не пишем?
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322204
Gustly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczGustly
Код: java
1.
2.
while ((cnt = r.read(bytes))!= -1)
writer.write(cnt);


Для вас это вообще непонятный набор букв и вы его переставляете как вам нравится, пока что-то не получится?
bytes - данные
cnt - количество прочитаных данных
writer.write(cnt) - пишем количество прочитаных данных как текст
А ожидаем почему-то данные, которые не пишем?
Слово bytes не стер, имелось в виду
Код: java
1.
2.
while ((cnt = r.read())!= -1)
writer.write(cnt);


В примере, который вы кидали используется массив, но без BufferedWriter, стоит ли его вообще тогда использовать? В доках написано, что он необходим, ибо быстрее и не напряжнее.
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322215
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GustlyВ примере, который вы кидали используется массив, но без BufferedWriter, стоит ли его вообще тогда использовать? В доках написано, что он необходим, ибо быстрее и не напряжнее.
Buffered классы можно читать и писать по символьно\побайтно, это проще.
Если писать через свой byte[] или char[], то проще накосячить, что вы уже и показали. Но если написать без ошибок, то Buffered классы не нужны.

Есть буфер - быстро
Нет буфера - медленно.
Два буфера медленнее чем один, а три буфера медленнее чем два.
У вас изначально 3 буфера: BufferedWriter, BufferedReader и char[] bytes.
IOUtils.copy -> один буфер.

Что тут не понятного?
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322221
Gustly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczGustlyВ примере, который вы кидали используется массив, но без BufferedWriter, стоит ли его вообще тогда использовать? В доках написано, что он необходим, ибо быстрее и не напряжнее.
Buffered классы можно читать и писать по символьно\побайтно, это проще.
Если писать через свой byte[] или char[], то проще накосячить, что вы уже и показали. Но если написать без ошибок, то Buffered классы не нужны.

Есть буфер - быстро
Нет буфера - медленно.
Два буфера медленнее чем один, а три буфера медленнее чем два.
У вас изначально 3 буфера: BufferedWriter, BufferedReader и char[] bytes.
IOUtils.copy -> один буфер.

Что тут не понятного?
Как пользоваться методом read() от BufferedReader и потом его писать. Я думал буферед должно быть в обе стороны чтения и записи. Как лучше поступить с именами файлов (они искажаются при вытаскивание из архива)? Оставить System.setProperty("file.encoding", "Cp1251"), а файлы считывать в UTF8 или еще как?
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322226
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gustly,

Я вам уже весь код привел. Нужно только два блока соединить

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
сopy( new ZipInputStream(blob.getBinaryStream()), new FileOutputStream(new File("C:\\" + e.getName())));

public static long copy(InputStream input, OutputStream output) throws IOException {

        byte[] buffer = new byte[MY_BUFFER_SIZE];
        long count = 0;
        int n = 0;

        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
        }
        return count;
}


Непосильная задача?
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322245
Gustly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz[/src]
Непосильная задача?
Это все понятно, спасибо. Искажение убралось строкой (buffer, 0, n), надо было окончание буфера указать. Ну и плюс с вашей помощью убраны ненужные BufferedWriter, хотя тогда она зачем они нужны, когда есть read(bufer).
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322254
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gustlyубраны ненужные BufferedWriter, хотя тогда она зачем они нужны, когда есть read(bufer)
Потому что такой код
Код: java
1.
2.
3.
4.
5.
6.
BufferedReader r = new BufferedReader(reader);
while ((c = reader.read())!= -1){
  if(c == '\n'){
      doSomething();
  }
}


Проще чем такой.

Код: java
1.
2.
3.
4.
5.
6.
7.
while ((c = r.read(buf))!= -1){
  for(int i = 0; i < c && i < buf.length; i ++){
      if(buf[i] == '\n'){
         doSomething();
      }
  }  
}
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322296
Gustly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczGustlyубраны ненужные BufferedWriter, хотя тогда она зачем они нужны, когда есть read(bufer)
Потому что такой код
Код: java
1.
2.
3.
4.
5.
6.
BufferedReader r = new BufferedReader(reader);
while ((c = reader.read())!= -1){
  if(c == '\n'){
      doSomething();
  }
}


Проще чем такой.

Код: java
1.
2.
3.
4.
5.
6.
7.
while ((c = r.read(buf))!= -1){
  for(int i = 0; i < c && i < buf.length; i ++){
      if(buf[i] == '\n'){
         doSomething();
      }
  }  
}


Я не понимаю как писать в файл, если читать через с = read(). Там число от 0 до 65к. Что потом? Writer.write(chr(c)) ?
...
Рейтинг: 0 / 0
BufferedReader и размер буфера
    #38322475
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gustly,

Я не врубаюсь куда вы смотрите.
Читаем int
http://docs.oracle.com/javase/6/docs/api/java/io/Reader.html#read()
Пишем int
http://docs.oracle.com/javase/6/docs/api/java/io/Writer.html#write(int)
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / BufferedReader и размер буфера
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]