本文介绍了通过FileSystem对象从文件系统读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

为了列出classpath上的特定目录的文件内容,我使用新的 FileSystem 和 Path Java 7的功能。在一个部署中,目录直接存储在文件系统中。在另一个部署中,它存储在JAR文件中。

In order to list file contents of a specific directory on classpath I'm using the new FileSystem and Path features of Java 7. In one deployment the directory is stored on file system, directly. In another deployment it is stored into a JAR file.

我的方法对JAR文件工作正常:我创建一个 FileSystem 对象,它引用JAR文件,并通过 Path 对象访问内容。

My approach works fine with JAR files: I create a FileSystem object which refers to the JAR file and access the content via Path object.

        ...
        URI dir = ...
        String[] array = dir.toString().split("!");

        try (final FileSystem fs = FileSystems.newFileSystem(URI.create(array[0]), new HashMap<String, Object>()))
        {
            final Path directory = fs.getPath(array[1]);
            try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(directory))
            {
        ...

由于dir对象具有以下值,它的作用如下:

Due to the dir object has following value, it works:

jar:file:/C:/Users/pax/.../Detector-1.0.jar!/org/.../destinationdir

但在其他环境中,目标目录直接存储在文件系统中。 dir对象包含值:

But in the other environment the destination directory is stored on file system, directly. dir object contains the value:

file:/C:/Users/pax/.../destinationdir

FileSystems.newFileSystem(...)总是抛出以下异常 / 和 file:/ C:/ Users / pax /.../ destinationdir as URI:

FileSystems.newFileSystem(...) always throws following exception for / and file:/C:/Users/pax/.../destinationdir as URI:

java.lang.IllegalArgumentException: Path component should be '/'
at sun.nio.fs.WindowsFileSystemProvider.checkUri(WindowsFileSystemProvider.java:68)

如何使用 FileSystem.newFileSystem 用于文件系统上的目的地?

How do you use FileSystem.newFileSystem for destinations on file system?

为了独立于其特定类型的存储(文件系统或JAR文件)列出目录内容,是否有更好的方法?

Is there a better approach in order to list the directories content independently from its specific kind of storage (file system or JAR file)?

推荐答案

以下问题的解决方案可以通过尝试解决问题(文件系统上的目标与JAR文件中的目标 catch方法:

Following question's resolution tackles the issue ("destination on file system" versus "destination in JAR file") by try-catch approach: NIO2: how to generically map a URI to a Path?

此实用程序方法尝试获取正确的路径实例。但是可能会出现另一个问题:如果此目标资源由JAR文件(而不是文件系统)包含,那么您只能通过其关联的 FileSystem 实例访问资源不能关闭!所以,你的帮助方法需要返回 Path 对象以及 FileSystem 实例(仅当它不在文件系统)。调用者必须手动关闭 FileSystem 对象:

This utility method tries to obtain a correct Path instance. But there may occur a further problem: If this destination resource is contained by a JAR file (instead of file system) then you can only access the resource via its associated FileSystem instance which must not be closed! So, your helper method needs to return the Path object as well as the FileSystem instance (only required if it's not on file system directly). The invoker has to close the FileSystem object, manually:

public static PathReference getPath(final URI resPath) throws IOException
{
    try
    {
        // first try getting a path via existing file systems
        return new PathReference(Paths.get(resPath), null);
    }
    catch (final FileSystemNotFoundException e)
    {
        /*
         * not directly on file system, so then it's somewhere else (e.g.:
         * JAR)
         */
        final Map<String, ?> env = Collections.emptyMap();
        final FileSystem fs = FileSystems.newFileSystem(resPath, env);
        return new PathReference(fs.provider().getPath(resPath), fs);
    }
}

包装类 PathReference 应实现 AutoClosable ,以便它可以在中使用尝试块:

The wrapper class PathReference should implement AutoClosable so that it can be used in try block:

public class PathReference implements AutoCloseable
{
   ...
    @Override
   public void close() throws Exception
    {
        if (this.fileSystem != null)
            this.fileSystem.close();
    }

    public Path getPath()
    {
        return this.path;
    }

    public FileSystem getFileSystem()
    {
        return this.fileSystem;
    }
}

这使得 FileSystem 实例更透明:

...
try (final PathReference fileObj = SignatureUtils.getPath(file))
{
    ...
    try (InputStream fileStream = Files.newInputStream(fileObj.getPath()))
    {
    ...

这篇关于通过FileSystem对象从文件系统读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-07 18:12