BufferedReader срещу конзола срещу скенер в Java

1. Общ преглед

В тази статия ще разгледаме разликите между класовете BufferedReader , Console и Scanner в Java .

За да се задълбочим по всяка тема, предлагаме да разгледате отделните ни статии за Java Scanner, Console I / O в Java и BufferedReader.

2. Потребителски вход

Като се има предвид основният поток, предаден на конструкторите, както класовете BufferedReader , така и Scanner могат да обработват по-широк диапазон от потребителски вход , като низ, файл, системна конзола (която обикновено е свързана с клавиатурата) и сокет.

От друга страна, класът Console е проектиран да осъществява достъп само до базираната на символи системна конзола, ако има такава, свързана с текущата виртуална машина на Java.

Нека да разгледаме конструкторите на BufferedReader , които приемат различни входове:

BufferedReader br = new BufferedReader( new StringReader("Bufferedreader vs Console vs Scanner in Java")); BufferedReader br = new BufferedReader( new FileReader("file.txt")); BufferedReader br = new BufferedReader( new InputStreamReader(System.in)) Socket socket = new Socket(hostName, portNumber); BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream())); 

Класът Scanner може също така да приема различни входове в своите конструктори:

Scanner sc = new Scanner("Bufferedreader vs Console vs Scanner in Java") Scanner sc = new Scanner(new File("file.txt")); Scanner sc = new Scanner(System.in); Socket socket = new Socket(hostName, portNumber); Scanner sc = new Scanner(socket.getInputStream());

Класът Console е достъпен само чрез извикване на метод:

Console console = System.console();

Моля, имайте предвид, че когато използваме клас Console , свързаната с JVM системна конзола не е налична, ако стартираме кода в IDE като Eclipse или IntelliJ IDEA.

3. Потребителски изход

За разлика от класовете BufferedReader и Scanner , които не записват нищо в изходния поток, класът Console предлага някои удобни методи като readPassword (String fmt, Object ... args), readLine (String fmt, Object ... args) и printf ( String format, Object ... args) , за да напишете подканата в изходния поток на системната конзола :

String firstName = console.readLine("Enter your first name please: "); console.printf("Welcome " + firstName );

Така че, когато пишем програма за взаимодействие със системната конзола, класът Console ще опрости кода, като премахне ненужното System.out.println .

4. Синтактичен вход

Класът Scanner може да анализира примитивни типове и низове, използвайки регулярни изрази .

Той разбива входа си в символи, използвайки персонализиран шаблон за разделител, който по подразбиране съвпада с празно пространство:

String input = "Bufferedreader vs Console vs Scanner"; Scanner sc = new Scanner(input).useDelimiter("\\s*vs\\s*"); System.out.println(sc.next()); System.out.println(sc.next()); System.out.println(sc.next()); sc.close();

Класовете BufferredReader и Console просто четат входния поток такъв, какъвто е.

5. Четене на защитени данни

Класът на конзолата има методи readPassword () и readPassword (String fmt , Object ... args) за четене на защитените данни с деактивирано ехо, така че потребителите няма да виждат какво пишат:

String password = String.valueOf(console.readPassword("Password :")); 

BufferedReader и Scanner нямат възможност да го направят.

6. Thread Safe

Методите за четене в BufferedReader и методите за четене и запис в Console са синхронизирани , докато тези в класа Scanner не са. Ако четем потребителския вход в многонишкова програма, или BufferedReader, или Console ще бъде по-добра опция.

7. Размер на буфера

Размерът на буфера е 8 KB в BufferedReader в сравнение с 1 KB в клас Scanner .

Освен това можем да посочим размера на буфера в конструктора на класа BufferedReader, ако е необходимо. Това ще помогне при четене на дългите низове от потребителския вход. Класът на конзолата няма буфер при четене от системната конзола , но има буфериран изходен поток за запис в системната конзола.

8. Разни

Има някои разлики, които не са основните фактори, които вземаме предвид при избора на подходящия клас за използване в различни ситуации.

8.1. Затваряне на входния поток

Once we create the instance of BufferedReader or Scanner, we need to remember to close it in order to avoid a memory leak. But this doesn't happen with the Console class — we don't need to close the system console after use.

8.2. Exception Handling

While Scanner and Console go with the unchecked exception approach, methods in BufferedReader throw checked exceptions, which forces us to write boilerplate try-catch syntax to handle the exceptions.

9. Conclusion

Now that we've stated the differences among these classes, let's come up with some rules of thumb regarding which one(s) are best suited to tackle different situations:

  • Use BufferedReader if we need to read long strings from a file, as it has better performance than Scanner
  • Consider Console if we're reading secure data from the system console and want to hide what is being typed
  • Use Scanner if we need to parse the input stream with a custom regular expression
  • Scanner would be preferred when we interact with the system console, as it offers fine-grained methods to read and parse the input stream. In addition, the performance drawback is not a big problem, as in most cases, the nextXXX methods are blocking and wait for manual input
  • В контекст, безопасен за нишки, помислете за BufferedReader, освен ако не трябва да използваме функции, специфични за класа Console