web-dev-qa-db-ja.com

whileループでBufferedReader.readLine()を適切に使用する

そのため、テキストファイルをプログラムに読み込むときに問題が発生します。コードは次のとおりです。

_     try{
        InputStream fis=new FileInputStream(targetsFile);
        BufferedReader br=new BufferedReader(new InputStreamReader(fis));

        //while(br.readLine()!=null){
        for(int i=0;i<100;i++){
            String[] words=br.readLine().split(" ");
            int targetX=Integer.parseInt(words[0]);
            int targetY=Integer.parseInt(words[1]);
            int targetW=Integer.parseInt(words[2]);
            int targetH=Integer.parseInt(words[3]);
            int targetHits=Integer.parseInt(words[4]);
            Target a=new Target(targetX, targetY, targetW, targetH, targetHits);
            targets.add(a);
        }
        br.close();
    }
    catch(Exception e){
        System.err.println("Error: Target File Cannot Be Read");
    }
_

私が読んでいるファイルは、引数の100行です。 forループを使用すると、完全に機能します。 whileステートメント(forループの上でコメント化されているステートメント)を使用すると、50で停止します。ユーザーが任意の行数のファイルでプログラムを実行できる可能性があるため、現在のforループの実装はできません。仕事。

while(br.readLine()!=null)が50で停止するのはなぜですか?テキストファイルを確認しましたが、ハングアップするものはありません。

Whileループを使用するときにtry-catchからエラーが発生しないため、困惑します。誰にもアイデアはありますか?

18
billg118

ループ内でもう一度br.readLine()を呼び出しています。
そのため、移動するたびにtwo行を読むことになります。

26
SLaks

また、非常に包括的な...

try{
    InputStream fis=new FileInputStream(targetsFile);
    BufferedReader br=new BufferedReader(new InputStreamReader(fis));

    for (String line = br.readLine(); line != null; line = br.readLine()) {
       System.out.println(line);
    }

    br.close();
}
catch(Exception e){
    System.err.println("Error: Target File Cannot Be Read");
}
36
ramin

次のような構造を使用できます。

 while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
10
Mona Jalal

まだこの質問につまずいている場合に備えて。最近では、Java 8:

try {
  Files.lines(Paths.get(targetsFile)).forEach(
    s -> {
      System.out.println(s);
      // do more stuff with s
    }
  );
} catch (IOException exc) {
  exc.printStackTrace();
}
7
ramin

SLaksとjpmの支援に感謝します。これは非常に単純なエラーで、私には見られませんでした。

SLaksが指摘したように、br.readLine()はループごとに2回呼び出されていたため、プログラムは半分の値しか取得できませんでした。修正されたコードは次のとおりです。

try{
        InputStream fis=new FileInputStream(targetsFile);
        BufferedReader br=new BufferedReader(new InputStreamReader(fis));
        String words[]=new String[5];
        String line=null;
        while((line=br.readLine())!=null){
            words=line.split(" ");
            int targetX=Integer.parseInt(words[0]);
            int targetY=Integer.parseInt(words[1]);
            int targetW=Integer.parseInt(words[2]);
            int targetH=Integer.parseInt(words[3]);
            int targetHits=Integer.parseInt(words[4]);
            Target a=new Target(targetX, targetY, targetW, targetH, targetHits);
            targets.add(a);
        }
        br.close();
    }
    catch(Exception e){
        System.err.println("Error: Target File Cannot Be Read");
    }

再度、感謝します!あなたたちは素晴らしいです!

3
billg118
Concept Solution:br.read() returns particular character's int value so loop 
continue's until we won't get -1 as int value and Hence up to there it print 
br.eadline() which returns a line into String form.
Way 1:
while(br.read()!=-1)
 {
  //continues loop until we won't get int value as a -1
  System.out.println(br.readLine());
 }
 Way 2:
 while((line=br.readLine())!=null)
 {
  System.out.println(line);
 }
 Way 3:
 for(String line=br.readLine();line!=null;line=br.readLine())
 {
  System.out.println(line);
 }``
 Way 4:
 It's an advance way to read file using collection and arrays concept 
 How we iterate using for each loop.

ここで確認してください http://www.Java67.com/2016/01/how-to-use-for-each-method-in-Java-8-examples.html

1
Chirag Shah

@raminによる答えに加えて、既にBufferedReaderまたはInputStreamがある場合、次のような行を反復処理することができます。

reader.lines().forEach(line -> {
    //...
});

または、指定された順序で処理する必要がある場合:

reader.lines().forEachOrdered(line -> {
    //...
});
1
Yauhen Parmon