【问题标题】:java.nio.file.FileSystemNotFoundException when getting file from resources folder从资源文件夹获取文件时出现 java.nio.file.FileSystemNotFoundException
【发布时间】:2015-06-27 02:33:30
【问题描述】:

我在以下代码中收到此错误(请注意,这不会发生在我的本地计算机上,仅发生在我的构建服务器上):

Files.readAllBytes(Paths.get(getClass().getResource("/elasticsearch/segmentsIndex.json").toURI()), Charset.defaultCharset());

还有例外:

Caused by: java.nio.file.FileSystemNotFoundException: null
at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
at java.nio.file.Paths.get(Paths.java:143)

我试图通过关注solution 来修复它;我的代码现在看起来像这样:

URI segmentsIndexURI = getClass().getResource("/elasticsearch/segmentsIndex.json").toURI();
Map<String, String> env = new HashMap<>(); 
env.put("create", "true");
FileSystem zipfs = FileSystems.newFileSystem(segmentsIndexURI, env); //exception here
Path segmentsIndexPath = Paths.get(segmentsIndexURI);

我收到以下异常:

java.lang.IllegalArgumentException: Path component should be '/'
at sun.nio.fs.UnixFileSystemProvider.checkUri(UnixFileSystemProvider.java:77)
at sun.nio.fs.UnixFileSystemProvider.newFileSystem(UnixFileSystemProvider.java:86)
at java.nio.file.FileSystems.newFileSystem(FileSystems.java:326)
at java.nio.file.FileSystems.newFileSystem(FileSystems.java:276)

似乎没有任何效果。 我应该如何构建文件的路径?

【问题讨论】:

  • 您是否注意到有问题的异常标题与帖子中的异常不同?请澄清。
  • 您将 file 的 URI 作为新的 file system 传递?我不知道这有什么意义。
  • 请注意,描述中提到的异常是我在遵循解决方案后得到的异常。第一个代码 sn-p 是在标题中引发异常的代码...如果您愿意,我也可以包含原始异常
  • 您是否打开了您的 jar 或目录部署以查看您的文件是否存在?在正确的地方?
  • 在我的本地机器上运行良好,所以我认为这与环境有关,否则路径在本地运行时将无法作为 wlel 运行

标签: java nio


【解决方案1】:

不要尝试访问文件等资源。只需抓住 InputStream 并从那里读取数据:

byte[] data;
try (InputStream in = getClass().getResourceAsStream("/elasticsearch/segmentsIndex.json")) {
    data = in.readAllBytes​(); // usable in Java 9+
    // data = IOUtils.toByteArray(in); // uses Apache commons IO library
}

此示例使用 Apache commons-io 库中的 IOUtils 类。

如果您的目标是 Java 9+,您也可以使用 data = in.readAllBytes​();

【讨论】:

  • 我必须添加getClass().getClassLoader()
【解决方案2】:

一般来说,假设每个资源都是一个文件是不正确的。相反,您应该获取该资源的 URL/InputStream 并从那里读取字节。番石榴可以提供帮助:

URL url = getClass().getResource("/elasticsearch/segmentsIndex.json");
String content = Resources.toString(url, charset);


另一个可能的解决方案,使用 InputStream 和 apache commons:Convert InputStream to byte array in Java

从一个byte[],简单的使用String构造函数获取内容为字符串。

【讨论】:

    【解决方案3】:

    如果你使用 Spring,注入资源。无论是文件,文件夹,甚至是多个文件,都有机会,你可以通过注入来做到这一点。警告:不要将FileFiles.walk 与注入的资源一起使用,否则以JAR 运行时会得到FileSystemNotFoundException

    此示例演示了注入位于static/img 文件夹中的多个图像。

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.core.io.Resource;
    import org.springframework.stereotype.Service;
    import javax.annotation.PostConstruct;
    
    @Service
    public class StackoverflowService {
    
        @Value("classpath:static/img/*")
        private Resource[] resources;
        private List<String> filenames;
    
        @PostConstruct
        void init() {
            final Predicate<String> isJPG = path -> path.endsWith(".jpg");
            final Predicate<String> isPNG = path -> path.endsWith(".png");
    
            // iterate resources, filter by type and get filenames
            filenames = Arrays.stream(resources)
                    .map(Resource::getFilename)
                    .filter(isJPG.or(isPNG))
                    .collect(Collectors.toList());
        }
    }
    

    【讨论】:

    • 这正是我需要的,不知道Resources[]的注入,谢谢!
    【解决方案4】:

    您应该通过InputStream 而不是File 获取资源,但不需要外部库。

    您只需要几行代码:

    InputStream is = getClass().getResourceAsStream("/elasticsearch/segmentsIndex.json");
    java.util.Scanner scanner = new java.util.Scanner(is).useDelimiter("\\A");
    String json = scanner.hasNext() ? scanner.next() : "";
    

    您可以在https://stackoverflow.com/a/5445161/968244了解更多关于该方法的信息

    【讨论】:

      【解决方案5】:

      您应该使用getResourceAsStream(…) 而不是getResource(…)。有许多方法可以将所有字节读入字节数组,例如Apache Commons 有一个实用方法可以做到这一点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-06
        • 2019-03-26
        • 2019-03-24
        • 2017-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多