Сканер против BufferedReader


284

Насколько я знаю, два наиболее распространенных метода чтения символьных данных из файла в Java - это использование Scannerили BufferedReader. Я также знаю, что BufferedReaderчитает файлы эффективно, используя буфер, чтобы избежать операций с физическим диском.

Мои вопросы:

  • Работает Scannerтак же хорошо, как BufferedReader?
  • Почему бы вы выбрали Scannerболее BufferedReaderили наоборот?

1
Я обычно также использую сканер для чтения из стандартного в («Scanner in = новый сканер (System.in)» чувствует себя намного чище). Не уверен, что это на самом деле менее эффективно, но поскольку чтение с std in блокирует, я не могу себе представить, что эффективность Scanner будет проблемой.
dimo414

Ответы:


201

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

Фактически вы можете передать a BufferedReaderв качестве scannerисточника символов для разбора.


55
BufferedReader синхронизирован, а Scanner - нет, поэтому вам решать.
Рувим

1
Я знаю, что эта тема старая, но у меня были неоднозначные результаты в операционных системах, использующих BufferedReader, при попытке вырвать содержимое из потоков, предоставляемых Process (т. Е. Захватить выходные данные внешней команды). Как только я изменил свой код, чтобы использовать вместо него Сканер, как отмечено в отдельном ответе , все стало работать согласованно и как ожидалось.
EWH

@Reuben Но в Scannerконечном счете зависит от чего-то еще для его ввода, который вполне может быть синхронизирован.
маркиз Лорн

189

В текущей версии / сборке JDK6 (b27) Scannerбуфер имеет меньший буфер ( 1024 символа ) по сравнению с BufferedReader( 8192 символа ), но этого более чем достаточно.

Что касается выбора, используйте, Scannerесли вы хотите проанализировать файл, используйте, BufferedReaderесли вы хотите читать файл построчно. Также см. Вводный текст их вышеупомянутой документации API.

  • Парсинг = интерпретация данного ввода как токенов (частей). Он может возвращать вам определенные части непосредственно как int, string, decimal и т. Д. См. Также все эти nextXxx()методы в Scannerклассе.
  • Чтение = немой поток Он возвращает вам все символы, которые вы, в свою очередь, должны вручную проверить, хотите ли вы подобрать или составить что-то полезное. Но если вам все равно не нужно этого делать, тогда чтения достаточно.

1
Хороший. Спасибо за подсказку буфера. Искал все это время, поскольку родные чтения чрезвычайно дороги.
Achow

7
@Asif: parsing = интерпретировать данный ввод как токены (части). Он может возвращать вам определенные части непосредственно как int, string, decimal и т. Д. См. Также все эти методы nextXxx () в классе Scanner. Чтение = немой поток Он возвращает вам все символы, которые вы, в свою очередь, должны вручную проверить, хотите ли вы подобрать или составить что-то полезное. Но если вам все равно не нужно этого делать, тогда чтения достаточно.
BalusC

@BalusC Хорошо, я уже использовал, readInt();readFloat (); и т. д. Теперь получил, что означает синтаксический анализ. и BalusC, можете ли вы уделить мне немного времени, всего 10 минут в чате, я хочу немного спросить о буферизованном, как это работает.
Асиф Муштак

Что я обертываю BufferedReaderв конструкторе сканера? Это хорошая идея?
Вивек

1
ScannerБуфер будет расширен по мере необходимости для сопоставления с образцом. Поэтому, если вам нужен больший буфер, вам нужно только вызвать его, например findWithinHorizon("\\z", 8192), для него и после него, он будет использовать буфер с емкостью 8192символов (или весь файл, если он меньше этого).
Хольгер

77

Смотрите эту ссылку , оттуда цитируется следующее:

BufferedReader - это простой класс, предназначенный для эффективного чтения из нижележащего потока. Как правило, каждый запрос на чтение, сделанный из Reader, такого как FileReader, вызывает соответствующий запрос на чтение в базовом потоке. Каждый вызов read () или readLine () может привести к тому, что байты будут считаны из файла, преобразованы в символы и затем возвращены, что может быть очень неэффективным. Эффективность значительно улучшается, если Reader деформируется в BufferedReader.

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

С другой стороны, в сканер встроено гораздо больше сыра; он может делать все, что может делать BufferedReader, и на том же уровне эффективности. Однако, кроме того, сканер может анализировать основной поток на предмет примитивных типов и строк с помощью регулярных выражений. Он также может маркировать основной поток с выбранным вами разделителем. Он также может выполнять прямое сканирование основного потока без учета разделителя!

Сканер, однако, не является поточно-ориентированным, он должен быть внешне синхронизирован.

Выбор использования BufferedReader или сканера зависит от кода, который вы пишете, если вы пишете простое средство чтения журнала Buffered reader достаточно. Однако, если вы пишете синтаксический анализатор XML, это более естественный выбор.

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


«Сканер, с другой стороны, имеет гораздо больше встроенного сыра; он может делать все, что может делать BufferedReader, и на том же уровне эффективности». Не согласен, BufferedReader немного быстрее по сравнению со Scanner, потому что Scanner выполняет анализ входных данных, а BufferedReader просто читает последовательность символов.
Пратик

40
  1. BufferedReaderимеет значительно большую буферную память, чем сканер. Используйте, BufferedReaderесли вы хотите получить длинные строки из потока, и используйте, Scannerесли вы хотите анализировать токен определенного типа из потока.

  2. ScannerМожно использовать токенизацию с использованием пользовательского разделителя и анализировать поток в примитивных типах данных, в то время как BufferedReaderможно только читать и хранить String.

  3. BufferedReaderсинхронно пока Scannerнет. Используйте, BufferedReaderесли вы работаете с несколькими потоками.

  4. Scannerскрывает IOException, в то время как BufferedReaderвыкидывает его немедленно.


18

Я предлагаю использовать BufferedReaderдля чтения текста. Scannerпрячется, IOExceptionа BufferedReaderсразу кидает.


12

Разница между BufferedReader и Scanner заключается в следующем:

  1. BufferedReader синхронизирован, но сканер не синхронизирован .
  2. BufferedReader является поточно-ориентированным, но Scanner не является поточно-ориентированным .
  3. BufferedReader имеет большую буферную память, но Scanner имеет меньшую буферную память .
  4. BufferedReader работает быстрее, но Scanner работает медленнее .
  5. Код для чтения строки из консоли:

    BufferedReader :

     InputStreamReader isr=new InputStreamReader(System.in);
     BufferedReader br= new BufferedReader(isr);
     String st= br.readLine();

    Сканер :

    Scanner sc= new Scanner(System.in);
    String st= sc.nextLine();

8

Ниже приведены различия между BufferedReader и сканером.

  1. BufferedReader только читает данные, но сканер также анализирует данные.
  2. вы можете читать только String с помощью BufferedReader, но вы можете читать int, long или float с помощью Scanner.
  3. BufferedReader более старый от Scanner, он существует от jdk 1.1, в то время как Scanner был добавлен в выпуске JDK 5.
  4. Размер буфера BufferedReader велик (8 КБ) по сравнению с 1 КБ сканера.
  5. BufferedReader больше подходит для чтения файла с длинной строкой, в то время как сканер больше подходит для чтения небольшого пользовательского ввода из командной строки.
  6. BufferedReader синхронизирован, а Scanner - нет, что означает, что вы не можете совместно использовать Scanner между несколькими потоками.
  7. BufferedReader работает быстрее, чем Scanner, потому что не тратит время на разбор
  8. BufferedReader немного быстрее по сравнению со сканером
  9. BufferedReader из пакета java.io, а сканер из пакета java.util на основании пунктов, которые мы можем выбрать по своему выбору.

Спасибо


6

Основные отличия:

  1. сканер

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

пример

 String input = "1 fish 2 fish red fish blue fish";
 Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
 System.out.println(s.nextInt());
 System.out.println(s.nextInt());
 System.out.println(s.next());
 System.out.println(s.next());
 s.close(); 

печатает следующий вывод:

 1
 2
 red
 blue 

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

 String input = "1 fish 2 fish red fish blue fish";

 Scanner s = new Scanner(input);
 s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
 MatchResult result = s.match();
 for (int i=1; i<=result.groupCount(); i++)
     System.out.println(result.group(i));
 s.close(); `


  1. BufferedReader:

    • Считывает текст из потока ввода символов, буферизует символы, чтобы обеспечить эффективное чтение символов, массивов и строк.

    • Размер буфера может быть указан, или размер по умолчанию может быть использован. Значение по умолчанию достаточно велико для большинства целей.

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

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

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

Источник: Ссылка


3

Существуют разные способы ввода данных в Java, такие как:

1) BufferedReader 2) Сканер 3) Аргументы командной строки

BufferedReader Чтение текста из потока ввода символов, буферизация символов, чтобы обеспечить эффективное чтение символов, массивов и строк.

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

если вы пишете простую программу чтения журнала, то буферная программа чтения подходит. если вы пишете анализатор XML, то сканер - более естественный выбор.

Для получения дополнительной информации, пожалуйста, обратитесь:

http://java.meritcampus.com/t/240/Bufferedreader?tc=mm69


1

Ответ ниже взят из Чтения из Консоли: JAVA Scanner vs BufferedReader

Когда вы читаете ввод с консоли, есть два варианта для достижения этой цели. Первое использование Scanner, другое использование BufferedReader. Оба они имеют разные характеристики. Это означает различия, как использовать это.

Сканер рассматривал данный ввод как токен. BufferedReader просто читает построчно данные, введенные как строка. Сканер сам по себе предоставляет возможности синтаксического анализа, такие как nextInt (), nextFloat ().

Но чем отличаются другие?

  • Сканер рассматривал данный ввод как токен. BufferedReader как строка потока / строка
  • Сканер токенизировал заданный вход с помощью регулярных выражений. При использовании BufferedReader необходимо написать дополнительный код
  • BufferedReader быстрее, чем Scanner * точка №. 2
  • Сканер не синхронизирован, BufferedReader синхронизирован

Сканер поставляется с JDK версии 1.5 и выше.

Когда следует использовать сканер или Buffered Reader?

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


0
  1. BufferedReader, вероятно, даст вам лучшую производительность (потому что Scanner основан на InputStreamReader, посмотрите источники).ups, для чтения из файлов он использует nio. Когда я проверял производительность nio по сравнению с BufferedReader для больших файлов, nio показывал немного лучшую производительность.
  2. Для чтения из файла попробуйте Apache Commons IO.

0

Я предпочитаю, Scannerпотому что он не генерирует проверенные исключения и, следовательно, его использование приводит к более упорядоченному коду.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.