如何将InputStream转换为FileInputStream

74

我在程序中有这行代码:

InputStream Resource_InputStream=this.getClass().getClassLoader().getResourceAsStream("Resource_Name");

但是我该如何从 [Resource_InputStream] 中获取 FileInputStream?


9
为什么需要它是一个FileInputStream? - nos
2
你确定你的资源是有实际文件支持的,而不是在一个JAR文件中的条目吗? - Adrian Pronk
3个回答

72

如果URI表示有效的本地磁盘文件系统路径,可以使用ClassLoader#getResource()来替代。

URL resource = classLoader.getResource("resource.ext");
File file = new File(resource.toURI());
FileInputStream input = new FileInputStream(file);
// ...
如果不行(例如JAR文件),那么最好的方法是将它复制到一个临时文件中。
Path temp = Files.createTempFile("resource-", ".ext");
Files.copy(classLoader.getResourceAsStream("resource.ext"), temp, StandardCopyOption.REPLACE_EXISTING);
FileInputStream input = new FileInputStream(temp.toFile());
// ...

话虽如此,我确实没有看到这样做的任何好处,除非是被一个需要FileInputStream而不是InputStream的糟糕的帮助类/方法所要求。如果可以的话,请修复API以请求一个InputStream。如果是第三方的,则应报告为错误。在这种特定情况下,我还会在该API的其余部分周围加上问号。


我使用了FileInputStream input = new FileInputStream(temp.toString());而不是FileInputStream input = new FileInputStream(temp.toFile());,因为temp.toFile可能会留下一个空的(FileInputStream)输入。你可以查看Path.toFile Java API文档来了解可能的原因。 - baron.wang

15

简而言之:不要将FileInputStream用作参数或变量类型,而应该使用抽象基类,在这种情况下是InputStream。


27
我不喜欢这个答案,因为有时你确实需要一个FileInputStream,例如你需要其API中的getChannel()方法,而他并没有询问使用InputStream是否是一个好主意,只是询问是否可以从InputStream创建一个文件输入流。你本可以在评论中进行说明,而不是添加新回答。请注意,我的翻译不包含任何解释和额外信息。 - arielsan
java.util.Properties怎么样? - niken

0
你需要类似这样的东西:
    URL resource = this.getClass().getResource("/path/to/resource.res");
    File is = null;
    try {
        is = new File(resource.toURI());
    } catch (URISyntaxException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    try {
        FileInputStream input = new FileInputStream(is);
    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

但它只能在你的IDE中工作,而不能在可运行的JAR文件中工作。我曾经遇到过同样的问题,解释在这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接