Java .util. nosuchelementexception -使用扫描器读取文件



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

我只想以以下格式读取一个txt文件:Double0 Double0 Int0Double1 Double1 Int1..双峰双峰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

根据JavaDoc nextDouble()扫描下一个令牌输入为双精度类型。此方法将抛出InputMismatchException,如果不能将下一个令牌转换为有效的双精度值。

所以这里Scanner不能在你的0,6580097206539348 0,36101701387184226 2行找到Double。有一个解决方案是在循环期间用.代替,(仅当您的每行不包含逗号时)

例如

  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

中了解更多信息

下一个输入应该总是是双精度体,对吗?因此,代替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();
    }
}

在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

输出显示良好

最新更新