从资源文件夹获取文件时java.nio.file.FileSystemNotFoundException

时间:2015-04-20 11:31:25

标签: java nio

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

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)

似乎没什么用。 我该如何构建文件的路径?

5 个答案:

答案 0 :(得分:10)

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

byte[] data;
try (InputStream in = getClass().getResourceAsStream("/elasticsearch/segmentsIndex.json")) {
    data = IOUtils.toByteArray(in);
}

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

答案 1 :(得分:4)

通常,假设每个资源都是文件是不正确的。相反,您应该获取该资源的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构造函数将内容作为字符串获取。

答案 2 :(得分:3)

您应该通过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

了解有关该方法的更多信息

答案 3 :(得分:0)

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

答案 4 :(得分:0)

如果使用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());
    }
}