2012-04-26 7 views
3

私はしばしばScannerクラスを使ってファイルを読むのが便利です。Scannerクラスはファイル全体を一度にメモリにロードしますか?

 String inputFileName; 
     Scanner fileScanner; 

     inputFileName = "input.txt"; 
     fileScanner = new Scanner (new File(inputFileName)); 

私の質問は、ファイル全体を一度にメモリにロードするのですか?またはファイルから

 fileScanner.nextLine(); 

読むようfileScanner上で以降の呼び出しを行う(すなわち、外部ストレージからではなくメモリから)?ファイルが大きすぎて一度にメモリに読み込むことができない場合、何が起こるか心配しているので私は尋ねる。ありがとう。

+1

答えはいいですが、バッファでファイルを読み取ります。つまり、チャンクであることを意味します。 – Alex

答えて

12

あなたがあなた自身で質問に答えることができます。

問題のスキャナコンストラクタの実装が示しているように見える:

public Scanner(File source) throws FileNotFoundException { 
     this((ReadableByteChannel)(new FileInputStream(source).getChannel())); 
} 

後者これはリーダーにラップされています

private static Readable makeReadable(ReadableByteChannel source, CharsetDecoder dec) { 
    return Channels.newReader(source, dec, -1); 
} 

そして、それはバッファサイズ

を使用して読み込まれます
private static final int BUFFER_SIZE = 1024; // change to 1024; 

建設連鎖の最終コンストラクタで確認できますように:

private Scanner(Readable source, Pattern pattern) { 
     assert source != null : "source should not be null"; 
     assert pattern != null : "pattern should not be null"; 
     this.source = source; 
     delimPattern = pattern; 
     buf = CharBuffer.allocate(BUFFER_SIZE); 
     buf.limit(0); 
     matcher = delimPattern.matcher(buf); 
     matcher.useTransparentBounds(true); 
     matcher.useAnchoringBounds(false); 
     useLocale(Locale.getDefault(Locale.Category.FORMAT)); 
    } 

したがって、スキャナはファイル全体を一度に読み取らないようです。

+0

+1ファイル全体を一度に読み取ることができなかったことを認識していませんでした。回答が編集されました。しかし、BufferedReader + FileReaderでは扱えない大きなファイルでも問題は発生します。 – Aidanc

+4

@Aidancどのような問題がありますか? –

0

大きなファイルの場合は、BufferedReaderFileReaderのようになります。基本的な例はhereです。

+0

@Sheriff edalorzoの答えを参照してください。私は、ファイル全体を読んでいると誤解されているようですが、Buffered + FileReaderは大きなファイルをより良く扱うので、私は答えを残しました。 – Aidanc

+2

@Aidanc - なぜそれを言うのですか?確かに、スキャナの解析機能が必要かどうかによって異なります。もちろん、OPが** only **でnextLine()を使うつもりならば、BufferedReaderは少し速くなります。 (OPが "fileScanner **の後続の** fileScanner.nextLine()" ...のように呼び出す) –

+1

なぜBufferedReaderが優れていると思いますか? – CodeBlue

1

コードを読むと、デフォルトで一度に1 KBが読み込まれるように見えます。長いテキスト行の場合、バッファーのサイズが大きくなります。 (あなたが持っているテキストのうち、最も長い行のサイズに)

0

ACMコンテストでは、高速読み込みが非常に重要です。 Javaでは、私たちは、あなたがキャッチするためにStringTokenizerを使用することができます

Red Alder 
Ash 
Aspen 
Basswood 
Ash 
Beech 
Yellow Birch 
Ash 
Cherry 
Cottonwood 

...ファイルが、その場合には、木の名前が含まれてい

FileInputStream inputStream = new FileInputStream("input.txt"); 
    InputStreamReader streamReader = new InputStreamReader(inputStream, "UTF-8"); 
    BufferedReader in = new BufferedReader(streamReader); 
    Map<String, Integer> map = new HashMap<String, Integer>(); 
    int trees = 0; 
    for (String s; (s = in.readLine()) != null; trees++) { 
     Integer n = map.get(s); 
     if (n != null) { 
      map.put(s, n + 1); 
     } else { 
      map.put(s, 1); 
     } 
    } 

...非常に速く、そのようなことをされて使用見つかりました見つかりましたあなたが望む行の部分。

大きなファイルにScannerを使用すると、いくつかのエラーが発生します。 10000行のファイルから100行を読み込みます!

スキャナーは、読み取り可能な インターフェイスを実装しているオブジェクトからテキストを読み取ることができます。基になる読み取り可能なメソッドの Readable.read(java.nio.CharBuffer)メソッドの呼び出しによってIOExceptionがスローされた場合、 スキャナは入力の終わりに達したとみなします。 基になる読み取り可能コードによってスローされた最新のIOExceptionは、ioException()メソッドによって取得された になります。

APIに

幸運を伝えます!

関連する問題