Java 解析.txt文件
Java parse .txt file
我试图在 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;
}
}
如堆栈跟踪所示,调用 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 语句轻松检查并检查异常前的最后一个语句是什么(在第一次或第二次调用 next() 之后)
您的 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.");
}
}
我试图在 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;
}
}
如堆栈跟踪所示,调用 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 语句轻松检查并检查异常前的最后一个语句是什么(在第一次或第二次调用 next() 之后)
您的 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.");
}
}