Scanner vs. BufferedReader

284

Até onde eu sei, os dois métodos mais comuns de leitura de dados baseados em caracteres de um arquivo em Java estão usando Scanneror BufferedReader. Sei também que os BufferedReaderarquivos de leitura são eficientemente usando um buffer para evitar operações no disco físico.

Minhas perguntas são:

  • Funciona Scannertão bem quanto BufferedReader?
  • Por que você escolher Scannersobre BufferedReaderou vice-versa?
Mads Mobæk
fonte
1
Geralmente, também uso o Scanner para ler em padrão ('Scanner in = new Scanner (System.in)' parece muito mais limpo). Não tenho certeza se isso é realmente menos eficiente, mas como a leitura de std in está bloqueando, não consigo imaginar a eficiência do Scanner.
Dimo414 #

Respostas:

201

Scanneré usado para analisar tokens do conteúdo do fluxo enquanto BufferedReaderapenas lê o fluxo e não faz nenhuma análise especial.

Na verdade, você pode passar a BufferedReaderpara a scannercomo a fonte dos caracteres a serem analisados.

Chandra Sekar
fonte
55
O BufferedReader é sincronizado e o Scanner não, portanto, cabe a você decidir.
Reuben
1
Sei que esse tópico é antigo, mas tive resultados mistos entre sistemas operacionais usando o BufferedReader ao tentar extrair conteúdo dos fluxos fornecidos pelo Process (por exemplo, capturar a saída de um comando externo). Depois que mudei meu código para usar o Scanner, conforme observado em uma resposta separada , as coisas começaram a se comportar de maneira consistente e conforme o esperado.
Ewh
@ Reuben Mas Scanner, em última análise, depende de outra coisa para sua entrada, que pode muito bem ser sincronizada.
Marquês de Lorne
189

Na versão / compilação mais recente do JDK6 (b27) atualmente, o Scanner possui um buffer menor ( 1024 caracteres ) em oposição aos BufferedReader( 8192 caracteres ), mas é mais que suficiente.

Quanto à escolha, use o Scanner se você deseja analisar o arquivo, use o BufferedReaderse você quiser ler o arquivo linha por linha. Consulte também o texto introdutório de suas documentações da API acima mencionadas.

  • Análise = interpretação da entrada fornecida como tokens (partes). É capaz de devolver partes específicas diretamente como int, string, decimal, etc. Veja também todos esses nextXxx()métodos na Scannerclasse.
  • Leitura = streaming estúpido. Ele continua devolvendo todos os personagens, que você, por sua vez, precisa inspecionar manualmente, se quiser combinar ou compor algo útil. Mas se você não precisa fazer isso de qualquer maneira, a leitura é suficiente.
BalusC
fonte
1
Agradável. Obrigado pela dica do buffer. Estava procurando isso o tempo todo, pois as leituras nativas são extremamente caras.
Achow
7
@Asif: parsing = interpretar a entrada fornecida como tokens (partes). É capaz de devolver partes específicas diretamente como int, string, decimal etc. Veja também todos os métodos nextXxx () na classe Scanner. Leitura = streaming estúpido. Ele continua devolvendo todos os personagens, que você, por sua vez, precisa inspecionar manualmente, se quiser combinar ou compor algo útil. Mas se você não precisa fazer isso de qualquer maneira, a leitura é suficiente.
precisa saber é o seguinte
@ BalusC Ok, eu já usei, readInt();readFloat (); Agora, entendi o que é o meio de analisar. e BalusC, você pode me dar pouco tempo apenas 10 minutos na sala de bate-papo, quero perguntar um pouco sobre o buffer, como ele funciona.
Asif Mushtaq
O que envolvo BufferedReaderno construtor do Scanner? isso é uma boa ideia?
precisa saber é
1
ScannerO buffer do será expandido conforme necessário para a correspondência de padrões. Portanto, se você deseja um buffer maior, basta invocar, por exemplo findWithinHorizon("\\z", 8192), nele e depois, ele usará um buffer com capacidade de 8192caracteres (ou o arquivo inteiro, se for menor que isso).
Holger
77

Veja este link , a seguir é citado a partir daí:

Um BufferedReader é uma classe simples destinada a ler com eficiência a partir do fluxo subjacente. Geralmente, cada solicitação de leitura feita de um Reader como um FileReader faz com que uma solicitação de leitura correspondente seja feita no fluxo subjacente. Cada chamada de read () ou readLine () pode fazer com que os bytes sejam lidos no arquivo, convertidos em caracteres e retornados, o que pode ser muito ineficiente. A eficiência é aprimorada consideravelmente se um Reader é distorcido em um BufferedReader.

O BufferedReader é sincronizado, portanto, as operações de leitura em um BufferedReader podem ser realizadas com segurança a partir de vários threads.

Um scanner, por outro lado, tem muito mais queijo embutido; ele pode fazer tudo o que um BufferedReader pode fazer e no mesmo nível de eficiência também. No entanto, além disso, um scanner pode analisar o fluxo subjacente para tipos e cadeias primitivas usando expressões regulares. Também pode tokenizar o fluxo subjacente com o delimitador de sua escolha. Ele também pode fazer a varredura direta do fluxo subjacente, desconsiderando o delimitador!

Um scanner, no entanto, não é seguro para threads, deve ser sincronizado externamente.

A escolha de usar um BufferedReader ou um Scanner depende do código que você está escrevendo, se estiver escrevendo um simples leitor de log O leitor tamponado é adequado. No entanto, se você estiver escrevendo um analisador de analisador XML, é a escolha mais natural.

Mesmo durante a leitura da entrada, se você deseja aceitar a entrada do usuário linha por linha e dizer apenas adicioná-la a um arquivo, um BufferedReader é bom o suficiente. Por outro lado, se você deseja aceitar a entrada do usuário como um comando com várias opções e, em seguida, pretende executar operações diferentes com base no comando e nas opções especificadas, um Scanner será mais adequado.

Jomoos
fonte
"Por outro lado, um scanner possui muito mais queijo embutido; ele pode fazer tudo o que um BufferedReader pode fazer e no mesmo nível de eficiência." Não concordo, o BufferedReader é um pouco mais rápido em comparação com o Scanner, porque o Scanner analisa os dados de entrada e o BufferedReader simplesmente lê a sequência de caracteres.
Pratik
40
  1. BufferedReaderpossui memória buffer significativamente maior que o Scanner. Use BufferedReaderse desejar obter seqüências longas de um fluxo e use Scannerse desejar analisar um tipo específico de token de um fluxo.

  2. Scannerpode usar tokenize usando delimitador personalizado e analisar o fluxo em tipos primitivos de dados, enquanto BufferedReadersó pode ler e armazenar String.

  3. BufferedReaderé síncrono enquanto Scannernão é. Use BufferedReaderse você estiver trabalhando com vários threads.

  4. Scanneroculta IOException enquanto BufferedReaderlança imediatamente.

Sujith PS
fonte
18

Eu sugiro usar BufferedReaderpara ler texto. Scanneresconde IOExceptionenquanto BufferedReaderjoga imediatamente.

Evgeniy
fonte
12

As diferenças entre o BufferedReader e o Scanner são as seguintes:

  1. BufferedReader está sincronizado, mas o Scanner não está sincronizado .
  2. BufferedReader é seguro para threads, mas o Scanner não está seguro para threads .
  3. BufferedReader tem memória buffer maior, mas o Scanner possui memória buffer menor .
  4. BufferedReader é mais rápido, mas o scanner é mais lento na execução .
  5. Código para ler uma linha do console:

    BufferedReader :

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

    Scanner :

    Scanner sc= new Scanner(System.in);
    String st= sc.nextLine();
Raman Gupta
fonte
8

A seguir, estão as diferenças entre o BufferedReader e o Scanner

  1. O BufferedReader lê apenas os dados, mas o scanner também analisa os dados.
  2. você só pode ler String usando o BufferedReader, mas pode ler int, long ou float usando o Scanner.
  3. O BufferedReader é mais antigo do Scanner, existe no jdk 1.1 enquanto o Scanner foi adicionado na versão JDK 5.
  4. O tamanho do buffer do BufferedReader é grande (8 KB) em comparação com 1 KB do scanner.
  5. O BufferedReader é mais adequado para leitura de arquivos com String longa, enquanto o Scanner é mais adequado para leitura de pequenas entradas do usuário no prompt de comando.
  6. O BufferedReader está sincronizado, mas o Scanner não, o que significa que você não pode compartilhar o Scanner entre vários threads.
  7. O BufferedReader é mais rápido que o Scanner porque não gasta tempo analisando
  8. BufferedReader é um pouco mais rápido em comparação com o Scanner
  9. O BufferedReader é do pacote java.io e o Scanner é do pacote java.util com base nos pontos que podemos selecionar.

obrigado

dhS
fonte
6

As principais diferenças:

  1. Scanner

  • Um scanner de texto simples que pode analisar tipos e cadeias primitivas usando expressões regulares.
  • Um scanner divide sua entrada em tokens usando um padrão delimitador, que por padrão corresponde a espaço em branco. Os tokens resultantes podem ser convertidos em valores de diferentes tipos usando os vários métodos seguintes.

Exemplo

 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(); 

imprime a seguinte saída:

 1
 2
 red
 blue 

A mesma saída pode ser gerada com esse código, que usa uma expressão regular para analisar todos os quatro tokens de uma vez:

 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:

    • Lê texto de um fluxo de entrada de caracteres, armazenando em buffer caracteres para fornecer uma leitura eficiente de caracteres, matrizes e linhas.

    • O tamanho do buffer pode ser especificado ou o tamanho padrão pode ser usado. O padrão é grande o suficiente para a maioria dos propósitos.

Em geral, cada solicitação de leitura feita de um Reader faz com que uma solicitação de leitura correspondente seja feita do fluxo de caracteres ou bytes subjacente. Portanto, é aconselhável envolver um BufferedReader em qualquer leitor cujas operações read () possam ser caras, como FileReaders e InputStreamReaders. Por exemplo,

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

armazenará em buffer a entrada do arquivo especificado. Sem buffer, cada chamada de read () ou readLine () pode fazer com que os bytes sejam lidos no arquivo, convertidos em caracteres e retornados, o que pode ser muito ineficiente. Os programas que usam DataInputStreams para entrada de texto podem ser localizados substituindo cada DataInputStream por um BufferedReader apropriado.

Fonte: Link

Shiva Nandam Sirmarigari
fonte
3

Existem diferentes maneiras de obter entrada em java como:

1) BufferedReader 2) Scanner 3) Argumentos da linha de comando

BufferedReader Leia o texto de um fluxo de entrada de caracteres, armazenando em buffer caracteres para fornecer uma leitura eficiente de caracteres, matrizes e linhas.

Onde Scanner é um scanner de texto simples que pode analisar tipos e cadeias primitivas usando expressões regulares.

se você estiver escrevendo um simples leitor de log, o leitor em buffer é adequado. se você estiver escrevendo um analisador de analisador XML, é a escolha mais natural.

Para mais informações, consulte:

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

manisha mulchandani
fonte
1

A resposta abaixo é retirada de Reading from Console: JAVA Scanner vs BufferedReader

Ao ler uma entrada do console, existem duas opções para isso. Primeiro usando Scanner, outro usando BufferedReader. Ambos têm características diferentes. Significa diferenças em como usá-lo.

O scanner tratou a entrada fornecida como token. BufferedReader apenas lê linha por linha, como entrada. O scanner fornece recursos de análise assim como nextInt (), nextFloat ().

Mas, quais são as outras diferenças entre eles?

  • O scanner tratou a entrada fornecida como token. BufferedReader como linha de fluxo / String
  • Entrada dada token do scanner usando regex. O uso do BufferedReader deve escrever código extra
  • BufferedReader mais rápido que o Scanner *, no. 2
  • O scanner não está sincronizado, BufferedReader sincronizado

O scanner vem desde o JDK versão 1.5 superior.

Quando deve usar o Scanner ou o Buffered Reader?

Observe as principais diferenças entre os dois: um usando token e outros usando a linha de fluxo. Quando você precisar de recursos de análise, use o Scanner. Mas, eu estou mais confortável com o BufferedReader. Quando você precisar ler um arquivo, use BufferedReader, porque é usar buffer ao ler um arquivo. Ou você pode usar o BufferedReader como entrada para o Scanner.

KNU
fonte
0
  1. O BufferedReader provavelmente fornecerá um melhor desempenho (porque o Scanner é baseado no InputStreamReader, procure fontes). ups, para ler arquivos que usa o nio. Quando testei o desempenho do nio contra o desempenho do BufferedReader para arquivos grandes, o nio mostra um desempenho um pouco melhor.
  2. Para ler um arquivo, tente o Apache Commons IO.
romano
fonte
0

Eu prefiro Scannerporque ele não lança exceções verificadas e, portanto, o uso resulta em um código mais simplificado.

thisismydesign
fonte