Java解析.text文件

时间:2015-01-07 20:52:39

标签: java java.util.scanner

我正在尝试在Netbeans IDE 8.0.2中运行以下文件TemplateMaker.java,并且遇到以下错误消息。 Netbeans没有显示红色指标供我修复。请帮忙。

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

2 个答案:

答案 0 :(得分:1)

您的processLine()期待“name = value”对。并且正如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.");
    }
}

答案 1 :(得分: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()两次。所以我假设有一个令牌,你读了两次。同样来自API的next()方法:

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

您可以通过添加System.out.println语句轻松检查,并检查异常之前的最后一个(在第一次或第二次调用next()之后)