【问题标题】:FileNotFoundException with FileInputStream even though .getResource(filename) finds it [duplicate]FileNotFoundException 与 FileInputStream 即使 .getResource(filename) 找到它[重复]
【发布时间】:2017-01-19 03:08:26
【问题描述】:

这是我在 stackoverflow 上提出的第一个问题,所以如果您发现我的问题中有不愉快/不好/不恰当的地方,请善待并指出给我。

我曾尝试用 Java 做我的学校作业,因为我厌倦了 C++,而且我已经用 Python 做过一些事情。但是,我在读取二进制文件时遇到了问题(该文件应按顺序包含一个双精度数和两个浮点数)。

具体来说:.getResource(filename) 找到文件,但是当我打开 FileInputStream(path)(在 public static Integer Leggere(Dati [] dato, String nomefile) 内)时,它会抛出 FileNotFoundException

这是我的代码:

import java.util.*;
import java.io.*;

public class Main{
    public static void main(String[] args) {
        Dati [] data  = new Dati[23500];
        int contatore = 0;
        for(; contatore < 23500; contatore++){
            data[contatore] = new Dati(0, 0, 0);
        }
        contatore = 0;

        String path = Dati.class.getClassLoader().getResource("valori.bin").getPath().toString();
        contatore = Leggere(data, path);
        Acquisire(data, contatore);
        Scrivere(data, "risultati.txt", contatore);
    }

    public static Integer Leggere(Dati [] dato, String nomefile){
        int j = 0;
        try{
            DataInputStream in = new DataInputStream(new FileInputStream(nomefile));
            while(in.available() > 0){
                dato[j].dato1 = in.readDouble();
                dato[j].dato2 = in.readFloat();
                dato[j].dato3 = in.readFloat();
                j++;
            }
            in.close();
        }
        catch(IOException e){
            System.out.println("Problemi nell'apertura del file");
            System.out.println(nomefile);
            System.exit(0);
        }

        return j;
    }

    public static void Scrivere(Dati [] dato, String nomefile, int count){
        PrintWriter output;
        try {
            output = new PrintWriter(nomefile);

            Integer j = 0;
            while(j < count){
                output.println(dato[j]);
                j++;
            }

            output.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


    }

    public static void Acquisire(Dati [] dato, int count){
        Scanner cinput = new Scanner(System.in);
        double c = 0.0;
        int j = 0;

        System.out.println("Inserisci un fattore di conversione: ");
        while(c == 0.0){
            c = cinput.nextDouble();
        }

        while(j < count){
            dato[j].dato1 *= c;
            dato[j].dato2 *= c;
            dato[j].dato3 *= c;
        }

        cinput.close();
    }
}

程序以两条处理异常的消息结束。第二个是getResource() 方法找到的文件路径:

Problemi nell'apertura del file
/C:/Users/Sebastian/Desktop/Archivio/Scuola/5C%20a.s.%202016-2017/Compiti%20Estate%202016/Informatica/03%20-%20Conversione/bin/valori.bin

我知道它是 FileNotFoundException,因为它在调试模式下是这样说的。

你会如何完成这段代码?你知道问题是什么吗?您能否发布一个解决问题的示例或解决该问题的替代方法示例?

问题的解决方案

我写这篇文章是为了让有类似问题的人可以找到他们的解决方案。

“故障”代码

String path = Dati.class.getClassLoader().getResource("valori.bin").getPath().toString();
DataInputStream in = new DataInputStream(new FileInputStream(path));

发生的事情是.getResource("valori.bin") 设法找到了文件(它的路径为.getPath()),但是当我尝试打开FileInputStream(path) 时,我得到了FileNotFoundException

工作代码

InputStream stream = Dati.class.getClassLoader().getResourceAsStream("valori.bin");
DataInputStream in = new DataInputStream(stream);

这样就可以了。通过这样做,我不需要担心路径名,因为.getResourceAsStream() 按原样返回可用的 Stream。我不知道为什么以前的代码不起作用,但启发式告诉我不要太担心,就这样吧!

【问题讨论】:

  • 在我的脑海中,其中一个 API 可能使用相对路径,而另一个需要绝对路径,您可能会弄错哪个路径。
  • @Tim Biegeleisen 哦,我明白了。好吧,FileInputStream() 将/C:/Users/Sebastian/Desktop/Archivio/Scuola/5C%20a.s.%202016-2017/Compiti%20Estate%202016/Informatica/03%20-%20Conversione/bin/valori.bin 作为参数。这是一条绝对路径,不是吗?
  • 文件名真的是这样吗,所有的 URL 编码?
  • @Robert 这是String path = Dati.class.getClassLoader().getResource("valori.bin").getPath().toString(); 在我使用 System.out 可视化它时给我的东西
  • 是的,但这是 URL 编码的,在某些情况下可能有意义。但是,文件系统不处理 URL 编码,而是按原样处理名称。使用 docs.oracle.com/javase/7/docs/api/java/net/… 恢复 URL 编码

标签: java filenotfoundexception fileinputstream getresource


【解决方案1】:

您可能想看看类加载器中的getResourceAsStream 方法。它为您提供了一个输入流,您可以直接插入,而不必处理完整路径和此类问题。

【讨论】:

  • 好的,谢谢。我已经尝试在 main:InputStream stream = Dati.class.getClassLoader().getResourceAsStream("valori.bin"); 中执行此操作,并更改了函数 Leggere() 中的所有内容以使其正常工作。现在看来它设法打开它,但是在从文件中读取几个字节后我遇到了 EOF 异常,但我想这是一个完全不同的问题要处理。是时候修复实际以二进制形式写入该文件的 Python 程序了。可能是因为我遇到了 Java 32 位浮点错误的 64 位 Python 浮点数。
猜你喜欢
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多