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


284

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

Мої запитання:

  • Діє Scannerтак само добре BufferedReader?
  • Чому б ви обрали Scannerбільше BufferedReaderчи навпаки?

1
Зазвичай я також використовую Scanner для читання зі стандартного в ("Scanner in = new Scanner (System.in)") відчуває себе набагато чистіше). Не впевнений, чи це насправді менш ефективно, але оскільки читання з std в блокується, я не можу уявити, що ефективність Сканера буде проблемою.
dimo414

Відповіді:


201

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

Насправді ви можете передати а BufferedReaderв scannerякості джерела символів для розбору.


55
BufferedReader синхронізований, а Сканер - ні, тож вирішувати вам.
Реубен

1
Я знаю, що ця тема стара, але я мав неоднозначні результати між операційними системами, які використовують BufferedReader, коли намагалися змусити вміст із потоків, передбачених Process (тобто збору результатів зовнішньої команди). Після того, як я змінив свій код, щоб замість цього скористатися Сканером, як зазначено в окремій відповіді , все почало поводитися послідовно та як очікувалося.
ewh

@Reuben Але в Scannerкінцевому рахунку залежить щось інше для його введення, яке цілком може бути синхронізованим.
Маркіз Лорн

189

В останній версії JDK6 випуску / збірки (b27), Scannerбуфер має менший розмір ( 1024 символів ) на відміну від BufferedReader( 8192 символів ), але це більш ніж достатньо.

Щодо вибору, використовуйте, Scannerякщо ви хочете проаналізувати файл, використовуйте, BufferedReaderякщо ви хочете прочитати файл за рядком. Також дивіться вступний текст їх попередньо зв'язаних документацій API.

  • Розбір = інтерпретація даного входу як лексеми (частини). Він може повернути вам конкретні частини безпосередньо як int, string, decimal тощо. Дивіться також усі ці nextXxx()методи в Scannerкласі.
  • Читання = німий потоковий. Він надає вам всі символи, які вам, в свою чергу, доведеться вручну перевірити, чи хочете ви співставити чи скласти щось корисне. Але якщо вам це все-таки не потрібно, то читання достатньо.

1
Хороший. Дякуємо за наконечник буфера. Шукав це весь час, оскільки рідні читають надзвичайно дорого.
Акція

7
@Asif: розбір = інтерпретація даного входу як лексеми (частини). Він може повернути вам певні частини безпосередньо у вигляді int, string, decimal тощо. Дивіться також всі методи nextXxx () у класі Scanner. Читання = німий потоковий. Він надає вам всі символи, які ви, в свою чергу, повинні перевірити вручну, чи хочете ви відповідати чи складати щось корисне. Але якщо вам це все-таки не потрібно, то читання достатньо.
BalusC

@BalusC Добре я вже використовував, readInt();readFloat (); і т. д. Тепер отримав те, що означає синтаксичний аналіз. і BalusC Ви можете трохи часу приділити мені лише 10 хвилин у чаті, я хочу трохи розпитати про буферизованих, як це працює.
Асиф Муштак

Що я обговорюю BufferedReaderв конструкторі сканера? це гарна ідея?
vivek

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

77

Дивіться це посилання , звідси цитується наступне:

BufferedReader - це простий клас, призначений для ефективного читання з нижнього потоку. Як правило, кожен запит на читання, зроблений з Reader, як FileReader, викликає відповідний запит читання до базового потоку. Кожне виклик read () або readLine () може спричинити зчитування байтів з файлу, перетворення їх у символи та повернення, що може бути дуже неефективно. Ефективність помітно підвищується, якщо зчитувач перекручується в BufferedReader.

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

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

Сканер, однак, не є безпечним для потоків, він повинен бути зовнішньо синхронізований.

Вибір використання BufferedReader або сканера залежить від коду, який ви пишете, якщо ви пишете простий читач журналів. Однак якщо ви пишете XML-аналізатор розбору сканерів - це більш природний вибір.

Навіть читаючи введення, якщо ви хочете прийняти користувальницький рядок за рядком і сказати просто додати його до файлу, BufferedReader досить хороший. З іншого боку, якщо ви хочете прийняти введення користувача як команду з декількома параметрами, а потім маєте намір виконувати різні операції на основі вказаних команд та параметрів, сканер підійде краще.


"Сканер, з іншого боку, має набагато більше сиру, вбудований у нього; він може зробити все, що може зробити BufferedReader, і на тому ж рівні ефективності." Не погоджуйтеся, BufferedReader трохи швидше порівняно зі сканером, оскільки Scanner аналізує вхідні дані, а BufferedReader просто зчитує послідовність символів.
Пратік

40
  1. BufferedReaderмає значно більшу буферну пам'ять, ніж сканер. Використовуйте, BufferedReaderякщо ви хочете отримати довгі рядки з потоку, і використовуйте, Scannerякщо ви хочете проаналізувати певний тип маркера з потоку.

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

  3. BufferedReaderє синхронним, поки Scannerнемає. Використовуйте, BufferedReaderякщо ви працюєте з декількома потоками.

  4. Scannerприховує IOException, при цьому BufferedReaderкидає його негайно.


18

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


12

Різниця між BufferedReader та сканером наступна:

  1. BufferedReader синхронізований, але Сканер не синхронізований .
  2. BufferedReader є безпечним для потоків, але Сканер не є безпечним для потоків .
  3. BufferedReader має більшу буферну пам'ять, але Scanner має меншу буферну пам'ять .
  4. BufferedReader швидше, але сканер повільніше у виконанні .
  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 та Scanner

  1. BufferedReader читає дані, але сканер також аналізує дані.
  2. ви можете читати String лише за допомогою BufferedReader, але ви можете читати int, long або float за допомогою Scanner.
  3. BufferedReader старший від Scanner, він існує від jdk 1.1, тоді як Scanner був доданий у версії JDK 5.
  4. Розмір буфера BufferedReader великий (8 КБ) порівняно з 1 КБ сканера.
  5. BufferedReader більше підходить для читання файлів з довгим рядком, тоді як Scanner більше підходить для зчитування невеликих даних користувача з командного рядка.
  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 навколо будь-якого зчитувача, чиї операції читання () можуть бути дорогими, наприклад 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

Відповідь нижче взята з Reading from Console: JAVA Scanner vs BufferedReader

Коли читаєте вхід з консолі, існує два варіанти для досягнення цього. Перше використання Scanner, інше використання BufferedReader. Вони обоє мають різні характеристики. Це означає відмінності, як ним користуватися.

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

Але, чим відрізняються інші?

  • Сканер обробляє даний вхід як маркер. BufferedReader як лінія потоку / рядок
  • Сканер токенізував даний вхід, використовуючи регулярний вираз. Використовуючи BufferedReader необхідно записати додатковий код
  • BufferedReader швидше, ніж сканер * точка немає. 2
  • Сканер не синхронізований, BufferedReader синхронізований

Сканер поставляється з JDK версії 1.5 вище.

Коли слід користуватися сканером чи буферним зчитувачем?

Подивіться на основні відмінності обох, одні використовують токенізовані, інші використовують потокову лінію. Коли вам потрібні можливості розбору, скористайтеся Сканером. Але мені зручніше з BufferedReader. Коли вам потрібно прочитати з файлу, використовуйте BufferedReader, оскільки це буфер використання під час читання файлу. Або ви можете використовувати BufferedReader як вхід до сканера.


0
  1. BufferedReader, ймовірно, дасть вам кращу ефективність (адже Scanner заснований на InputStreamReader, дивіться джерела). ups, для читання з файлів він використовує nio. Коли я перевіряв nio продуктивність на BufierReader для великих файлів, nio демонструє дещо кращу ефективність.
  2. Для читання з файлу спробуйте AOche Commons IO.

0

Я вважаю за краще, Scannerоскільки він не викидає перевірені винятки, і тому результати використання є більш спрощеним кодом.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.