2015-01-07 96 views
0

我想在Netbeans IDE 8.0.2中運行下面的文件TemplateMaker.java,並且遇到以下錯誤消息。 Netbeans沒有顯示我要修復的紅色指標。請幫忙。Java解析.txt文件

Exception in thread "main" java.util.NoSuchElementException 
    at java.util.Scanner.throwFor(Scanner.java:907) 
    at java.util.Scanner.next(Scanner.java:1416) 
    at templatemaker.TemplateMaker.processLine(TemplateMaker.java:48) 
    at templatemaker.TemplateMaker.processLineByLine(TemplateMaker.java:35) 
    at templatemaker.TemplateMaker.main(TemplateMaker.java:17) 
Java Result: 1 

這裏是我的源代碼:

package templatemaker; 


import java.io.IOException; 
import java.nio.charset.Charset; 
import java.nio.charset.StandardCharsets; 
import java.nio.file.Path; 
import java.nio.file.Paths; 
import java.util.Scanner; 


public class TemplateMaker { 

     public static void main(String [] args) 
throws IOException { 
    TemplateMaker parser = new TemplateMaker("Book1.txt"); 
    parser.processLineByLine(); 
    log("Done."); 
    } 

    /** 
    Constructor. 
    @param aFileName full name of an existing, readable file. 
    */ 
    public TemplateMaker(String aFileName){ 
    fFilePath = Paths.get(aFileName); 
    } 


    /** Template method that calls {@link #processLine(String)}. 
    * @throws java.io.IOException */ 
    public final void processLineByLine() throws IOException { 
    try (Scanner scanner = new Scanner(fFilePath, ENCODING.name())){ 
     while (scanner.hasNextLine()){ 
     processLine(scanner.nextLine()); 
     }  
    } 
    } 


    protected void processLine(String aLine){ 
    //use a second Scanner to parse the content of each line 
    Scanner scanner = new Scanner(aLine); 
    scanner.useDelimiter("="); 
    if (scanner.hasNext()){ 
     //assumes the line has a certain structure 
     String name = scanner.next(); 
     String value = scanner.next(); 
     log("Name is : " + quote(name.trim()) + ", and Value is : " + quote(value.trim())); 
    } 
    else { 
     log("Empty or invalid line. Unable to process."); 
    } 
    } 

    // PRIVATE 
    private final Path fFilePath; 
    private final static Charset ENCODING = StandardCharsets.UTF_8; 

    private static void log(Object aObject){ 
    System.out.println(String.valueOf(aObject)); 
    } 

    private String quote(String aText){ 
    String QUOTE = "'"; 
    return QUOTE + aText + QUOTE; 
    } 
} 
+5

你用'hasNext()檢查'一次,然後讀兩遍。不是一個好主意。 – MightyPork

+4

爲什麼不使用調試器並單步執行代碼? – tier1

+0

甚至不需要調試器。正常的控制檯輸出就足夠了;) – ProgrammingIsAwsome

回答

1

您的processLine()期望有一個「名稱=值」對。正如MightyPork所說的,你正在檢查hasNext()一次,然後再讀兩遍。因此,如果該行沒有=符號,則該掃描程序將不會得到next()令牌。您應該添加兩個hasNext()檢查。理想情況下,你不需要掃描儀。因爲你總是希望通過=分隔兩個令牌,你可以簡單地依靠java.util.StringTokenizer作爲

protected void processLine(String aLine){ 
    StringTokenizer st = new StringTokenizer(aLine, "="); 
    if(st.countTokens() == 2) { 
     log("Name is : " + quote(st.nextToken().trim()) + ", and Value is : " + quote(st.nextToken().trim())); 
    } else { 
     log("Empty or invalid line. Unable to process."); 
    } 
} 
0

由於堆棧跟蹤表明,異常被拋出時scanner.next()被調用

at java.util.Scanner.next(Scanner.java:1416) 

if (scanner.hasNext()){ 
     //assumes the line has a certain structure 
     String name = scanner.next(); // checked by hasNext() 
     String value = scanner.next(); // not checked by hasNext() 
     log("Name is : " + quote(name.trim()) + ", and Value is : " + quote(value.trim())); 
} 

誤差必須在第二個.next()。您檢查掃描器是否有下一個標記,但是您調用.next()兩次。所以我假設還有1個令牌,你讀了兩次。還從API的next()方法:

Throws: 
    NoSuchElementException - if no more tokens are available 
    IllegalStateException - if this scanner is closed 

您可以檢查很容易被添加的System.out.println語句,並檢查有什麼異常前的最後一輪(未來的第一或第二個電話後( ))