线程“main”中的Java异常java.util.NoSuchElementException - 使用scanner来读取文件

时间:2014-06-19 02:06:02

标签: java

我已经搜索了关于这个主题的各种主题,但是找不到任何处于相同情况的人或者我目前可以使用的任何解决方案。

我只想读取以下格式的txt文件: Double0 Double0 Int0 Double1 Double1 Int1 .. Doublen Doublen Intn

这是我的代码:

public void readDatabase(String s) throws FileNotFoundException{    
    try {               
            BufferedReader br = new BufferedReader(new FileReader(s));
            String line = br.readLine();
            Scanner trainFile = null;
            while (line != null) {      
                line.trim();
                trainFile = new Scanner(line);
                double x = trainFile.nextDouble();
                double y = trainFile.nextDouble();
                int type = trainFile.nextInt();
                this.database.add(new Point(x,y,type));
                line = br.readLine();
            }   
            trainFile.close();
            br.close();
    }
    catch (IOException ioe) {
        ioe.printStackTrace();
    }
}

有趣的是,这个功能工作了一段时间,但是当我用更多数据填充txt文件时,它停止工作。我还检查了文件是否存在错误,但一切都很好。根据我的堆栈跟踪,错误出现在第一个NextDouble()调用。有没有人有想法?

更新

以下是正在运行的文件类型:

0,6580097206539348  0,36101701387184226 2
0,9529350156283241  0,7383387609711926  2
0,6580097206539348  0,36101701387184226 2
0,9529350156283241  0,7383387609711926  2
0,6580097206539348  0,36101701387184226 2
0,48639272096486486 0,4378985495387871  1

但如果我添加一些这样的额外行,它就会停止工作:

0,6580097206539348  0,36101701387184226 2
0,9529350156283241  0,7383387609711926  2
0,6580097206539348  0,36101701387184226 2
0,9529350156283241  0,7383387609711926  2
0,6580097206539348  0,36101701387184226 2
0,48639272096486486 0,4378985495387871  1
0,8632344357711337  0,5253407956535258  1
0,7351912765040557  0,8295830810436339  1
0,6369155743204543  0,2757349130759706  1
0,46512947234632146 0,4388586141249502  1
0,8677892876429869  0,599451235810409   1
0,8827084731154641  0,55652107505414    1

3 个答案:

答案 0 :(得分:1)

  

根据JavaDoc nextDouble()扫描下一个令牌   输入为double.This方法将抛出InputMismatchException if   下一个标记无法转换为有效的双精度值。

因此Scanner无法在您的专栏Double中找到0,6580097206539348 0,36101701387184226 2。有一种解决方案是在循环期间将,替换为.(仅当您的每一行不包含逗号而非此目的时)

例如

  String yourLine="0,6580097206539348  0,36101701387184226 2"
  Scanner trainFile = new Scanner(line.replace(',', '.'));
               double x = trainFile.nextDouble();
               double y = trainFile.nextDouble();
               int type = trainFile.nextInt();

此外,为了从Exception中幸存,您可以使用hasNextDoubel()hasNextInt()方法让Scanner检查数据中是否存在double / int,它会返回true/false。您可以在#Scanner

了解详情

答案 1 :(得分:0)

在java中,由于逗号代替小数,因此无法解析双精度数。编辑文件以使用句点而不是逗号。

我通过运行以下函数测试了代码:

public static void readDatabase(String s) throws FileNotFoundException {

    File file = new File(s);
    Scanner scanner = new Scanner(file);

    while (scanner.hasNextLine()) {
        String line = scanner.nextLine();
        String[] values = line.split(" ");
        double x = Double.parseDouble(values[0]);
        double y = Double.parseDouble(values[1]);
        int type = Integer.parseInt(values[2]);
        System.out.println(x + " : " + y + " : " + type);
    }
    scanner.close();
}

在文件上:

1.1 1.2 1 
2.1 2.2 2 
3.1 3.2 3

得到了结果:

1.1 : 1.2 : 1
2.1 : 2.2 : 2
3.1 : 3.2 : 3

请注意,我的代码根据找到的空格分隔行,而不是使用扫描程序搜索双打/整数。在平面文件中,最好使用标准格式化(空格,逗号,冒号等)而不是格式化文件,这样就可以更容易地解析文件。

修改

如果您希望保持平面文件的格式不变,只需将逗号更改为句点即可解决您的问题。我使用了您的函数(将数据库行更改为输出):

public static void readDatabase(String s) throws IOException {

    BufferedReader br = new BufferedReader(new FileReader(s));
    String line = br.readLine();
    Scanner trainFile = null;
    while (line != null) {
        line.trim();
        trainFile = new Scanner(line);
        double x = trainFile.nextDouble();
        double y = trainFile.nextDouble();
        int type = trainFile.nextInt();
        System.out.println(x + " : " + y + " : " + type);
        line = br.readLine();
    }
    trainFile.close();
    br.close();
}

在文件上(这是您提供的数据,逗号更改为句点):

0.6580097206539348  0.36101701387184226 2
0.9529350156283241  0.7383387609711926  2
0.6580097206539348  0.36101701387184226 2
0.9529350156283241  0.7383387609711926  2
0.6580097206539348  0.36101701387184226 2
0.48639272096486486 0.4378985495387871  1
0.8632344357711337  0.5253407956535258  1
0.7351912765040557  0.8295830810436339  1
0.6369155743204543  0.2757349130759706  1
0.46512947234632146 0.4388586141249502  1
0.8677892876429869  0.599451235810409   1
0.8827084731154641  0.55652107505414    1

输出显示正常。

答案 2 :(得分:0)

下一个输入总是是双倍的,对吗?因此,而不是while(line != null)(当您有空行时将返回true),请检查while(scanner.hasNextDouble())

public void readDatabase(String s) throws FileNotFoundException{    
    try {               
        final BufferedReader br = new BufferedReader(new FileReader(s));
        final Scanner trainFile = new Scanner(br);
        while (trainFile.hasNextDouble()) {      
            double x = trainFile.nextDouble();
            double y = trainFile.nextDouble();
            int type = trainFile.nextInt();
            this.database.add(new Point(x,y,type));
        }   
        trainFile.close();
        br.close();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
}

您仍需要将逗号更改为小数点。否则上述情况将无效。

如果您的文件有逗号而您需要将其解释为小数点,那么您可以尝试以下操作:

public void readDatabase(String s) throws FileNotFoundException{    
    try {               
        final BufferedReader br = new BufferedReader(new FileReader(s));
        String line = br.readLine();
        while(line != null) {
            line = line.replace(',', '.');
            final Scanner lineScanner = new Scanner(line);
            if(!scanner.hasNextDouble())
                break;// quit loop
            // else continue loop
            double x = lineScanner.nextDouble();
            double y = lineScanner.nextDouble();
            int type = lineScanner.nextInt();
            this.database.add(new Point(x,y,type));
            line = br.readLine();
        }   
        br.close();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
}