2015-01-07 5 views
0

Я пытаюсь запустить приведенный ниже файл TemplateMaker.java в Netbeans IDE 8.0.2 и запущен в следующее сообщение об ошибке. Netbeans не показывает никаких красных индикаторов для меня. Пожалуйста помоги.Java parse .txt file

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() один раз, а затем читаете дважды. Так что, если эта строка не имеет символа =, это сломается, так как сканер не получит токен . Вы должны добавить две проверки 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

Как StackTrace указывает, то исключение при 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 следующий метод():

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

Вы можете проверить, что легко добавив заявление System.out.println и проверить, что это последний перед исключением (после первого или второго вызова следующего ())