2012-11-15 53 views
11

Vì vậy, tôi gặp sự cố khi đọc tệp văn bản trong chương trình của mình. Đây là mã:Sử dụng BufferedReader.readLine() trong một vòng lặp while đúng cách

 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"); 
    } 

Tệp tôi đọc từ 100 dòng đối số. Nếu tôi sử dụng vòng lặp for thì nó hoạt động hoàn hảo. Nếu tôi sử dụng câu lệnh while (người nhận xét ở trên vòng lặp) thì nó dừng ở mức 50. Có khả năng người dùng có thể chạy chương trình với một tệp có số dòng bất kỳ, vì vậy việc triển khai vòng lặp hiện tại của tôi giành được ' t làm việc.

Tại sao dòng while(br.readLine()!=null) dừng ở mức 50? Tôi đã kiểm tra các tập tin văn bản và không có gì có thể treo nó lên.

Tôi không nhận được bất kỳ lỗi nào từ try-catch khi tôi sử dụng vòng lặp while nên tôi bị bối rối. Ai có ý tưởng gì không?

Trả lời

24

Bạn đang gọi số br.readLine() lần thứ hai trong vòng lặp.
Do đó, bạn sẽ chỉ đọc hai dòng mỗi khi bạn đi xung quanh.

+0

Cảm ơn bạn! Tôi chắc chắn đã nhận thấy điều này. Bạn có biết cách giải quyết nào không? – billg118

+4

Cú pháp '((line = br.readLine())! = Null)' được cho phép trong Java, phải không? – jpm

+2

@jpm: Có; đó là cách tốt nhất để làm điều này. (mặc dù tôi muốn đặt 'null' trước để làm cho nó rõ ràng hơn) – SLaks

3

Cảm ơn bạn đã hỗ trợ SLaks và jpm. Đó là một lỗi khá đơn giản mà tôi chỉ đơn giản là không nhìn thấy.

Như SLaks đã chỉ ra, br.readLine() được gọi hai lần mỗi vòng lặp làm cho chương trình chỉ nhận được một nửa giá trị. Đây là mã cố định:

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"); 
    } 

Cảm ơn bạn lần nữa! Các bạn rất tuyệt!

+0

Cũng thể hiện sự khai thác tuyệt vời của tính bất biến của các chuỗi. – JoshuaTree

25

cũng rất toàn diện ...

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"); 
} 
+0

Đây là cách để đi cho tôi. 'while ((line = br.readLine())! = null)' quá xấu. Tôi không thích gọi 'br.readLine()' hai lần nhưng không có nhiều bạn có thể làm về điều đó. Tôi sẽ rút ngắn câu lệnh 'for' thành' cho (String s = br.readLine(); s! = Null; s = br.readLine()) ' – Adam

+1

Tôi thích cú pháp vòng lặp cho nên bạn không có biến treo xung quanh sau vòng lặp. Ngoài ra nó có thể được rút ngắn một chút, vẫn còn xấu xí: 'for (String line = null; null! = (Line = reader.readLine());)' ** Lưu ý: ** sử dụng 'reader.readLine() 'trong điều kiện và khởi tạo của' for' làm cho dòng đầu tiên bị bỏ qua. – Raystorm

5

Bạn có thể sử dụng một cấu trúc như sau:

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

Trong trường hợp nếu bạn vẫn đang vấp phải câu hỏi này. Ngày nay mọi thứ trông đẹp hơn với Java 8:

try { 
    Files.lines(Paths.get(targetsFile)).forEach(
    s -> { 
     System.out.println(s); 
     // do more stuff with s 
    } 
); 
} catch (IOException exc) { 
    exc.printStackTrace(); 
} 
Các vấn đề liên quan