スキャナーとBufferedReader


284

私の知る限り、Javaのファイルから文字ベースのデータを読み取る最も一般的な2つの方法は、Scannerまたはを使用することBufferedReaderです。またBufferedReader、物理ディスク操作を回避するためにバッファを使用することで効率的にファイルを読み取ることも知っています。

私の質問は:

  • DOESはScanner実行だけでなく、BufferedReader
  • なぜあなたは選ぶだろうScannerオーバーBufferedReaderまたはその逆?

1
私は通常、標準からの読み取りにもスキャナーを使用します(「スキャナーイン=新しいスキャナー(システム。それが実際に効率が悪いかどうかはわかりませんが、標準入力からの読み取りがブロックされているため、スキャナーの効率が問題になるとは思えません。
dimo414

回答:


201

ScannerストリームをBufferedReader読み取るだけで、ストリームのコンテンツからトークンを解析するために使用され、特別な解析は行いません。

実際、解析する文字のソースとしてa BufferedReaderをaに渡すことができますscanner


55
BufferedReaderは同期され、Scannerは同期されないため、ユーザーが決定します。
ルーベン

1
私はこのトピックが古いことを知っていますが、Processedによって提供されるストリームからコンテンツを取得する(つまり、外部コマンドの出力をキャプチャする)ときに、BufferedReaderを使用するオペレーティングシステム間で結果が混在しています。別の回答に記載されているように、代わりにスキャナーを使用するようにコードを変更する、物事は一貫して期待どおりに動作し始めました。
2013年

@Reubenしかし、Scanner最終的には入力が別のものに依存しているため、同期が取れている可能性があります。
ローン侯爵

189

現在最新のJDK6リリース/ビルド(b27)では、 Scanner、(8192文字)とは異なり、バッファのサイズ(1024文字)は小さくていますが、これで十分です。BufferedReader

選択については、ファイルScanner解析するBufferedReader場合はを使用し、ファイルを1行ずつ読み取る場合はを使用します。また、事前にリンクされたAPIドキュメントの紹介文も参照してください。

  • 解析 =与えられた入力をトークン(パーツ)として解釈します。特定の部分をint、string、decimalなどとして直接返すことができます。クラスnextXxx()内のこれらすべてのメソッドも参照してくださいScanner
  • 読書 =ダムストリーミング。それはあなたにあなたにすべてのキャラクターを返し続けます、そしてあなたはあなたが今あなたがマッチするか、または何か有用なものを作りたいかどうかを手動で検査しなければならないのです。しかし、とにかくそれを行う必要がない場合は、読書で十分です。

1
良いですね。バッファチップをありがとう。ネイティブリードは非常に高価であるため、ずっと探していました。
Achow 2012

7
@Asif:解析=指定された入力をトークン(パーツ)として解釈します。特定の部分をint、string、decimalなどとして直接返すことができます。ScannerクラスのすべてのnextXxx()メソッドも参照してください。読み取り=ダムストリーミング。それはあなたにあなたにすべてのキャラクターを返し続けます、そしてあなたはあなたが今あなたがマッチするか、または何か有用なものを作りたいかどうかを手動で検査しなければならないのです。しかし、とにかくそれを行う必要がない場合は、読書で十分です。
BalusC 2015

@BalusC OKすでに使用しました、readFloat readInt();(); など。解析の意味がわかりました。BalusCは、チャットルームでわずか10分の時間を与えてくれますか。バッファリングのしくみについて少し質問したいと思います。
Asif Mushtaq 2015

BufferedReaderスキャナーのコンストラクターで何をラップしますか?これは良いアイデアですか?
vivek

1
Scannerのバッファは、パターンマッチングのために必要に応じて拡張されます。したがって、より大きなバッファが必要な場合は、たとえばfindWithinHorizon("\\z", 8192)、その上で呼び出すだけでよく、その後、8192charの容量を持つバッファ(またはそれよりも小さい場合はファイル全体)を使用します。
Holger

77

このリンクを参照してください、以下はそこから引用されています:

BufferedReaderは、基になるストリームから効率的に読み取ることを目的とした単純なクラスです。一般に、FileReaderのようなReaderで行われた各読み取り要求は、対応する読み取り要求を基になるストリームに対して行います。read()またはreadLine()を呼び出すたびに、ファイルからバイトが読み取られ、文字に変換されて返される可能性がありますが、これは非常に非効率的です。リーダーがBufferedReaderでワープされると、効率はかなり向上します。

BufferedReaderは同期されているため、BufferedReaderでの読み取り操作は複数のスレッドから安全に実行できます。

一方、スキャナーにはより多くのチーズが組み込まれています。BufferedReaderが実行できるすべてのことを、同じレベルの効率で実行できます。ただし、さらにスキャナーは、正規表現を使用して、プリミティブ型と文字列の基になるストリームを解析できます。また、選択した区切り文字を使用して、基になるストリームをトークン化することもできます。デリミタを無視して、基になるストリームのフォワードスキャンも実行できます。

ただし、スキャナーはスレッドセーフではないため、外部で同期する必要があります。

単純なログリーダーを作成している場合は、バッファー付きリーダーで十分です。ただし、XMLパーサーを作成する場合は、スキャナーがより自然な選択です。

入力を読み取っているときでも、ユーザー入力を1行ずつ受け入れて、ファイルに追加するだけであれば、BufferedReaderで十分です。一方、ユーザー入力を複数のオプションを持つコマンドとして受け入れ、指定したコマンドとオプションに基づいてさまざまな操作を実行する場合は、スキャナーの方が適しています。


「一方、スキャナーには、より多くのチーズが組み込まれています。BufferedReaderが実行できるすべてのことを、同じレベルの効率で実行できます。」同意しないでください。Scannerは入力データの解析を行い、BufferedReaderは単に文字のシーケンスを読み取るため、BufferedReaderはScannerに比べて少し高速です。
Pratik、2018

40
  1. BufferedReaderスキャナーよりも大幅に大きなバッファーメモリを備えています。使用BufferedReaderあなたがストリーム、および使用から長い文字列を取得したい場合Scanner、あなたは、ストリームから特定のタイプのトークンを解析したい場合。

  2. Scannerカスタムデリミタを使用してトークン化を使用し、ストリームをプリミティブ型のデータに解析BufferedReaderできますが、文字列の読み取りと保存のみが可能です。

  3. BufferedReader同期しScannerていますが、同期していません。BufferedReader複数のスレッドで作業している場合に使用します。

  4. ScannerIOExceptionをBufferedReaderすぐにスローする間、それを隠します。


18

私はBufferedReaderテキストを読むのに使うことを勧めます。すぐに投げながらScanner隠れる。IOExceptionBufferedReader


12

BufferedReaderScannerの違いは次のとおりです。

  1. BufferedReaderは同期されていますが、スキャナーは同期されてません
  2. BufferedReaderはスレッドセーフですが、スキャナーはスレッドセーフではありません
  3. BufferedReaderのバッファメモリは大きいが、スキャナのバッファメモリは小さいです。
  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とScannerの違いです。

  1. BufferedReaderはデータを読み取るだけですが、スキャナーもデータを解析します。
  2. BufferedReaderを使用してのみ文字列を読み取ることができますが、スキャナーを使用してint、long、floatを読み取ることができます。
  3. BufferedReaderはScannerよりも古いものですが、JDK 5リリースでScannerが追加されたときにjdk 1.1から存在します。
  4. 1KBのスキャナーと比較して、BufferedReaderのバッファーサイズは大きい(8KB)。
  5. BufferedReaderは長い文字列のファイルを読み取るのに適していますが、Scannerはコマンドプロンプトから小さなユーザー入力を読み取るのに適しています。
  6. BufferedReaderは同期されますが、Scannerは同期されません。つまり、複数のスレッド間でScannerを共有できません。
  7. BufferedReaderは、解析に時間を費やさないため、スキャナーよりも高速です。
  8. BufferedReaderは、スキャナーと比較して少し高速です
  9. 選択したポイントに基づいて、BufferedReaderはjava.ioパッケージから、Scannerは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 

このコードで同じ出力を生成できます。このコードでは、正規表現を使用して4つのトークンすべてを一度に解析します。

 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:

    • 文字入力ストリームからテキストを読み取り、文字をバッファリングして、文字、配列、および行の効率的な読み取りを提供します。

    • バッファサイズを指定するか、デフォルトのサイズを使用できます。デフォルトはほとんどの目的に十分な大きさです。

一般に、Readerで作成された各読み取り要求は、対応する読み取り要求を基になる文字またはバイトストリームで作成します。したがって、FileReadersやInputStreamReadersなど、read()操作にコストがかかる可能性のあるリーダーをBufferedReaderでラップすることをお勧めします。例えば、

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スキャナーvs BufferedReader

コンソールから入力を読み取る場合、それを実現するための2つのオプションがあります。最初にを使用しScanner、別の使用BufferedReaderます。どちらも特徴が異なります。それは使い方の違いを意味します。

スキャナーは与えられた入力をトークンとして扱いました。BufferedReaderは、入力が文字列として指定された行を1行ずつ読み取るだけです。スキャナーは、nextInt()、nextFloat()と同様に、解析機能を提供します。

しかし、他の違いは何ですか?

  • スキャナーは与えられた入力をトークンとして扱いました。Streamed / StringとしてのBufferedReader
  • スキャナーは、正規表現を使用して与えられた入力をトークン化しました。BufferedReaderを使用するには、追加のコードを記述する必要があります
  • BufferedReaderはScannerより高速です*ポイントなし。2
  • スキャナーが同期されていない、BufferedReaderが同期されている

JDKバージョン1.5以降のスキャナーが付属しています。

スキャナーまたはバッファーリーダーはいつ使用する必要がありますか?

両方の主な違いを見てください。1つはトークン化を使用し、もう1つはストリームラインを使用しています。解析機能が必要な場合は、代わりにスキャナーを使用してください。しかし、私はBufferedReaderの方が快適です。ファイルから読み取る必要がある場合は、BufferedReaderを使用してください。これは、ファイルを読み取るときにバッファーを使用するためです。または、BufferedReaderをスキャナーへの入力として使用できます。


0
  1. BufferedReaderを使用すると、おそらくパフォーマンスが向上します(スキャナーはInputStreamReaderに基づいているため、ソースを参照します)。ups、nioを使用してファイルから読み取るため。大きなファイルのBufferedReaderパフォーマンスに対してnioパフォーマンスをテストしたところ、nioは少し優れたパフォーマンスを示しています。
  2. ファイルから読み取るには、Apache Commons IOを試してください。

0

Scannerチェックされた例外をスローしないので、使用によりコードがより合理化されるので、私は好みます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.