Может ли BufferedReader читать байты?

Извините, если этот вопрос повторяется, но я не получил ответа, который искал.

Документы Java говорят это

В общем, каждый запрос на чтение, сделанный Reader, вызывает соответствующий запрос на чтение базового потока символов или байтов. Поэтому рекомендуется обернуть BufferedReader вокруг любого Reader, чьи операции read() могут быть дорогостоящими, например, FileReaders > и InputStreamReaders. Например,

BufferedReader in = new BufferedReader(new FileReader("foo.in"));

будет буферизовать ввод из указанного файла. Без буферизации каждый вызов read() или readLine() может привести к считыванию байтов из файла, преобразованию их в символы и последующему возврату, что может быть очень неэффективно.

  1. Мой первый вопрос: если bufferedReader может читать байты, то почему мы не можем работать с изображениями, которые находятся в байтах, используя bufferedreader.

  2. Мой второй вопрос: хранит ли Bufferedreader символы в BUFFER и что означает эта строка?

будет буферизовать ввод из указанного файла.

  1. Мой третий вопрос: что означает эта строка

В общем, каждый запрос на чтение, сделанный Reader, приводит к тому, что соответствующий запрос на чтение будет сделан из базового потока символов или байтов.


person TruePS    schedule 06.03.2014    source источник


Ответы (3)


  1. По умолчанию он преобразуется в символ, но когда у вас есть изображение, у вас не может быть символьных данных, вместо этого вам нужны данные в пикселях байтов. Таким образом, вы не можете использовать его.

  2. Это буферизация, то есть чтение определенного фрагмента данных в массиве символов. Вы можете увидеть это поведение в коде:

 public BufferedReader(Reader in) {
               this(in, defaultCharBufferSize);
            }

а значение по умолчаниюCharBufferSize указано ниже:

частный статический интервал по умолчаниюCharBufferSize = 8192;

3 Every time you do read operation, it will be reading only one character.

Таким образом, в двух словах, буферизация означает, что сначала будет прочитано несколько фрагментов символьных данных, которые будут храниться в массиве символов, которые будут обработаны, и снова он будет читать тот же фрагмент данных, пока не достигнет конца потока.

Вы можете обратиться к следующему, чтобы узнать больше

BufferedReader

person UVM    schedule 06.03.2014
comment
скажем, у меня есть текстовый файл test.txt, содержащий три строки ›How ›are ›you Это означает, что Bufferedreader сначала читает первую строку, т.е. How, и помещает ее в буфер, затем читает are и помещает ее в буфер, а затем вы и помещаете ее в буфер. Я прав? Итак, когда буфер станет пустым? - person TruePS; 06.03.2014
comment
Он будет считывать n байтов или данных символов и сохранять их в массив символов вместо того, чтобы снова и снова читать из ввода-вывода. Помните, что каждая операция чтения обходится дороже и влияет на производительность. Давайте файл, имеющий 20000 байт, используя стратегию буферизации, вы сначала прочитаете, скажем, 512 байт и сохраните его в виде массива, вместо того, чтобы каждый раз читать один байт для всех этих 20000 символов. - person UVM; 06.03.2014
comment
Таким образом, он будет читать целых 3 строки How are you и сохраняет их в массиве символов, а массив символов находится в буфере в памяти. Таким образом, bufferedreader будет читать все данные из буфера и отображать их, а после чтения всех данных он очищает буфер. Я прямо сейчас? - person TruePS; 06.03.2014
comment
Чтение массива символов БУФЕРИЗИРУЕТСЯ. Вы можете видеть это в приведенной выше ссылке, которую я упомянул. - person UVM; 06.03.2014
comment
ссылка, которую вы мне дали, выходит за рамки моей лиги, я просто хочу получить ответ на мой предыдущий комментарий, так как весь процесс После этого я не буду тратить ваше драгоценное время, поэтому, пожалуйста, помогите мне, дав ответ на мой предыдущий комментарий, пожалуйста плз. - person TruePS; 06.03.2014
comment
1. он создаст массив символов с размером по умолчанию и прочитает столько символов в этот массив, а не строку. Затем он сформирует строку строки из этого массива символов и вернется к вам, когда вы вызовете readLine(). Как он сохраняется в массиве символов, перейдите к методу readLine() в приведенной выше ссылке. Там вы можете увидеть, как используется этот массив символов. Надеюсь, теперь это ясно для вас. - person UVM; 06.03.2014
comment
Я немного не понимаю, как работает readline(), но спасибо за вашу огромную помощь. Я хотел бы поговорить с вами на эту тему, ваши знания о Java действительно потрясающие. Большое вам спасибо. - person TruePS; 06.03.2014

Здесь есть два вопроса.

<сильный>1. Буферизация

Представьте, что вы живете в миле от ближайшего источника воды и каждый час выпиваете чашку воды. Ну, ты же не будешь ходить за каждой чашкой к воде. Ходите один раз в день и возвращайтесь домой с ведром воды, достаточным для того, чтобы наполнить чашку 24 раза.

Сегмент — это буфер.

Представьте, что в вашу деревню подается вода из реки. Но иногда река пересыхает на месяц; в других случаях река приносит так много воды, что деревня затапливается. Итак, вы строите плотину, а за плотиной находится водохранилище. Водохранилище наполняется в сезон дождей и постепенно опорожняется в сухой сезон. Деревня получает стабильный поток воды круглый год.

Резервуар представляет собой буфер.

Потоки данных в вычислениях аналогичны обоим этим сценариям. Например, вы можете получить несколько килобайт данных из файловой системы за один системный вызов ОС, но если вы хотите обрабатывать по одному символу за раз, вам нужно что-то похожее на резервуар.

BufferedReader содержит в себе другой Reader (например, FileReader), который является рекой, и массив байтов, который является резервуаром. Каждый раз, когда вы читаете из него, он делает что-то вроде:

 if there are not enough bytes in the "reservoir" to fulfil this request
      top up the "reservoir" by reading from the underlying Reader
 endif
 return some bytes from the "reservoir".

Однако когда вы используете BufferedReader, вам не нужно знать, как он работает, достаточно знать, что он работает.

<сильный>2. Подходит для изображений

Важно понимать, что BufferedReader и FileReader являются примерами Readers. Возможно, вы еще не изучали полиморфизм в своем обучении программированию, поэтому, когда вы это сделаете, помните об этом. Это означает, что если у вас есть код, который использует FileReader, но только те его аспекты, которые соответствуют Reader, то вы можете заменить его на BufferedReader, и он будет работать точно так же.

Это хорошая привычка объявлять переменные как наиболее общий класс, который работает:

 Reader reader = new FileReader(file);

... потому что тогда это будет единственное изменение, которое вам нужно для добавления буферизации:

 Reader reader = new BufferedReader(new FileReader(file));

Я пошел по этому пути, потому что все Reader меньше подходят для изображений.

Reader имеет два метода read:

 int read(); // returns one character, cast to an int
 int read(char[] block); // reads into block, returns how many chars it read

Вторая форма не подходит для изображений, потому что она определенно читает символы, а не целые числа.

Первая форма выглядит так, как будто все в порядке — в конце концов, она читает целые числа. И действительно, если вы просто используете FileReader, это вполне может сработать.

Однако подумайте о том, как будет работать BufferedReader, обернутый вокруг FileReader. При первом вызове BufferedReader.read() он вызовет FileReader.read(buffer) для заполнения своего буфера. Затем он вернет первый char буфера обратно в int и вернет его.

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

Поэтому, если вы хотите читать целые числа, используйте InputStream, а не Reader. InputStream имеет int read(byte[] buf, int offset, int length) -- байты гораздо надежнее возвращаются из int и обратно, чем chars.

person slim    schedule 06.03.2014
comment
Спасибо, что написали для меня такую ​​длинную статью. Я очень ценю это, но другие пользователи, которые ответили, знают, как работает BufferedReader, поэтому я также хотел расширить свои знания о том, как это работает. BufferedReader, обернутый вокруг FileReader, будет работать и относительно buffer . - person TruePS; 06.03.2014
comment
Просто хотел сказать, отличный ответ. - person Matthias; 22.07.2016

Читатели (и писатели) в java — это специализированные классы для работы с текстовыми (символьными) потоками — понятие строки не имеет смысла в любом другом типе потока.

общий эквивалент ввода-вывода см. в BufferedInputStream

Итак, отвечая на ваши вопросы:

  1. в то время как считыватель в конечном итоге читает байты, он преобразует их в символы. он не предназначен для чтения чего-либо еще (например, изображений) - используйте для этого семейство классов InputStream
  2. буферизованный считыватель будет считывать большие блоки данных из базового потока (который может быть файлом, сокетом или чем-либо еще) в буфер в памяти, а затем будет обслуживать запросы на чтение из этого буфера, пока буфер не опустеет. такое поведение чтения больших фрагментов вместо меньших фрагментов каждый раз повышает производительность.
  3. это означает, что если вы не заключаете считыватель в буферизованный считыватель, то каждый раз, когда вы хотите прочитать один символ, он будет обращаться к disk.network, чтобы получить только один символ, который вы хотите. выполнение операций ввода-вывода такими маленькими порциями обычно плохо сказывается на производительности.
person radai    schedule 06.03.2014
comment
можете ли вы ответить на этот вопрос [stackoverflow.com/questions/22199220/]. Пожалуйста, помогите, если можете - person TruePS; 06.03.2014
comment
Я понял первую и третью точку, но не понял вторую точку. Создает ли буферизованный считыватель новый буфер каждый раз, когда читает строку, и вы говорите, что буферизованный считыватель считывает данные из буфера, поэтому он экономит наше время? - person TruePS; 06.03.2014
comment
@TruePS - нет, работает с одним буфером. он обслуживает запросы на чтение из этого буфера, и когда буфер становится пустым, он считывает фрагмент из основного потока/читателя/чего-либо, чтобы заполнить буфер. и да, это значительно повышает производительность. - person radai; 06.03.2014
comment
Хорошо, теперь я понял, просто последнее, скажем, у меня есть текстовый файл test.txt, содержащий три строки ‹code›How‹code› ‹code›are‹code› ‹code›you?‹code› Это означает, что Bufferedreader сначала прочитал сначала line, т.е. как и помещает его в буфер, затем он считывает и помещает его в буфер, а затем вы и помещаете его в буфер. Я прав? Итак, когда буфер станет пустым? - person TruePS; 06.03.2014