将 `java.nio.file.Path` 转换为 `File` 失败。

huangapple go评论80阅读模式
英文:

converting java.nio.file.Path to File got failed

问题

以下是您要翻译的内容:

我正在尝试将 .cer 文件打包到一个 jar 文件中,并使用 Java 动态将它们安装到密钥库中。

private List<File> doSomething(Path p) {
       
        List<File> FileList = new ArrayList<>();
        try {
            
            int level = 1;
            if (p.toString().equals("BOOT-INF/classes/certs")) {
                level = 2;

                Stream<Path> walk = Files.walk(p, level);
                for (Iterator<Path> it = walk.iterator(); it.hasNext(); ) {
                    System.out.println(it.next());//获取文件夹中的所有 .cer 文件
                      FileList.add(it.next().toFile());//出现错误:UnsupportedOperationException,无法关联 Path
                }
                
                logger.info("fileList" + FileList.size());
            }
        }
        catch(Exception e)
        {
            logger.error("error-----------"+e);
        }
        return FileList;
    }

我在使用 toFile() 方法时遇到了 UnsupportedOperationException,我认为这是因为我正在尝试访问 jar 文件内部的文件。是否有方法可以将这个 Path(nio.file.Path)转换为实际的文件或流?

英文:

I am trying to get .cer files packed inside a jar and install them dynamically to keystore using java .

private List&lt;File&gt; doSomething(Path p)  {
       
        List&lt;java.io.File&gt;FileList=new ArrayList&lt;&gt;();
        try {
            
            int level = 1;
            if (p.toString().equals(&quot;BOOT-INF/classes/certs&quot;)) {
                level = 2;

                Stream&lt;Path&gt; walk = Files.walk(p, level);
                for (Iterator&lt;Path&gt; it = walk.iterator(); it.hasNext(); ) {
                    System.out.println(it.next());//getting all .cer files in the folder
                      FileList.add(it.next().toFile());//getting an error UnsupportedOperationException Path not associated with
                }
                
                logger.info(&quot;fileList&quot; + FileList.size());
            }
        }
        catch(Exception e)
        {
            logger.error(&quot;error-----------&quot;+e);
        }
        return FileList;
    }

I am getting UnsupportedOperationExceptionin toFile(), believe this is because I am trying to access file inside a jar.
Is there any way to conver this Path(nio.file.Path) to actual file or stream?

答案1

得分: 1

Path#toString() 方法不会返回使用正斜杠(/)表示的路径,而是会返回使用反斜杠(\)表示的路径,因此您的比较将永远不会返回 true。

当从本地文件系统读取路径时,始终使用与系统相关的路径或文件分隔符。为了做到这一点,您可以使用 String#replaceAll() 方法将任何路径名中的斜杠转换为适用于代码所在文件系统的分隔符,例如:

String pathToCompare = "BOOT-INF/classes/certs"
                       .replaceAll("[\\/]", "\\" + File.separator);

这样应该可以正常工作:

private List<java.io.File> doSomething(java.nio.file.Path p) {
    java.util.List<java.io.File> FileList = new java.util.ArrayList<>();
    try {
        int level = 1;
        String pathToCompare = "BOOT-INF/classes/certs"
                               .replaceAll("[\\/]", "\\" + File.separator);
        if (p.toString().equals(pathToCompare)) {
            level = 2;
            java.util.stream.Stream<Path> walk = java.nio.file.Files.walk(p, level);
            for (java.util.Iterator<Path> it = walk.iterator(); it.hasNext();) {
                System.out.println(it.next());//getting all .cer files in the folder
                FileList.add(it.next().toFile());//getting an error UnsupportedOperationException Path not associated with
            }
        }
    }
    catch (Exception e) {
        System.err.println(e);
    }
    return FileList;
}

> 编辑:

如果您想要基于特定的文件扩展名或者 JAR 文件的内容进行列举,那么您需要做一些不同的事情。下面的代码与您之前使用的代码非常相似,唯一的区别在于:

  • 方法名改为 getFilesList()
  • 列举返回的是 List<String> 而不是 List<File>
  • 深度级别现在是传递给方法的参数(始终确保深度级别足够执行任务);
  • 方法还添加了一个可选的字符串参数(命名为 onlyExtensions),以便可以应用一个或多个文件扩展名,返回一个只包含文件名包含所应用扩展名的路径列表。如果提供的扩展名是 ".jar",那么该 JAR 文件的内容也将应用于返回的列表。如果没有提供任何扩展名,则列表中将返回所有文件。

对于 JAR 文件,还提供了一个辅助方法:

根据需要修改这些代码:

public static List<String> getFilesList(String thePath, int depthLevel, String... onlyExtensions) {
    Path p = Paths.get(thePath);
    java.util.List<String> FileList = new java.util.ArrayList<>();
    try {
        java.util.stream.Stream<Path> walk = java.nio.file.Files.walk(p, depthLevel);
        for (java.util.Iterator<Path> it = walk.iterator(); it.hasNext();) {
            File theFile = it.next().toFile();
            if (onlyExtensions.length > 0) {
                for (String ext : onlyExtensions) {
                    ext = ext.trim();
                    if (!ext.startsWith(".")) {
                        ext = "." + ext;
                    }
                    if (!theFile.isDirectory() && theFile.getName().substring(theFile.getName().lastIndexOf(".")).equalsIgnoreCase(ext)) {
                        FileList.add(theFile.getName() + " --> " + theFile.getAbsolutePath());
                    }
                    else if (!theFile.isDirectory() && theFile.getName().substring(theFile.getName().lastIndexOf(".")).equalsIgnoreCase(".jar")) {
                        List<String> jarList = getFilesNamesFromJAR(theFile.getAbsolutePath());
                        for (String strg : jarList) {
                            FileList.add(theFile.getName() + " --> " + strg);
                        }
                    }
                }
            }
            else {
                FileList.add(theFile.getAbsolutePath());
            }
        }
    }
    catch (Exception e) {
        System.err.println(e);
    }
    return FileList;
}

辅助方法用于 JAR 文件

```java
public static java.util.List<String> getFilesNamesFromJAR(String jarFilePath) {
    java.util.List<String> fileNames = new java.util.ArrayList<>();
    java.util.zip.ZipInputStream zip = null;
    try {
        zip = new java.util.zip.ZipInputStream(new java.io.FileInputStream(jarFilePath));
        for (java.util.zip.ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
            fileNames.add(entry.getName());
        }
    }
    catch (java.io.FileNotFoundException ex) {
        System.err.println(ex);
    }
    catch (java.io.IOException ex) {
        System.err.println(ex);
    }
    finally {
        try {
            if (zip != null) {
                zip.close();
            }
        }
        catch (IOException ex) {
            System.err.println(ex);
        }
    }
    return fileNames;
}

使用 **getFileList()** 方法的示例用法可能如下所示

```java
List<String> fileNames = getFilesList("C:\\MyDataFolder", 3, ".cer", ".jar");

// Display files in fileNames List
for (String str : fileNames) {
    System.out.println(str);
}
英文:

Path#toString() won't return the path with forward slashes (/) like the string path you are comparing to. It returns it with back-slashes (\) so your comparison won't ever become true.

When reading paths from the local file System always use the path or file separator related to the System. To do this you can use the String#replaceAll() method to convert any path name slashes to what is appropriate for the file system your code is operating on, for example:

String pathToCompare = &quot;BOOT-INF/classes/certs&quot;
.replaceAll(&quot;[\\/]&quot;, &quot;\\&quot; + File.separator);

This should work fine:

private List&lt;java.io.File&gt; doSomething(java.nio.file.Path p) {
java.util.List&lt;java.io.File&gt; FileList = new java.util.ArrayList&lt;&gt;();
try {
int level = 1;
String pathToCompare = &quot;BOOT-INF/classes/certs&quot;
.replaceAll(&quot;[\\/]&quot;, &quot;\\&quot; + File.separator);
if (p.toString().equals(pathToCompare)) {
level = 2;
java.util.stream.Stream&lt;Path&gt; walk = java.nio.file.Files.walk(p, level);
for (java.util.Iterator&lt;Path&gt; it = walk.iterator(); it.hasNext();) {
System.out.println(it.next());//getting all .cer files in the folder
FileList.add(it.next().toFile());//getting an error UnsupportedOperationException Path not associated with
}
}
}
catch (Exception e) {
System.err.println(e);
}
return FileList;
}

> EDIT:

If you want to base your listing on specific file extensions and or the contents of a JAR file then you will need to do something a little different. The code below is very similar to the code you have been using with the exception that:

  • the method name is changed to getFilesList();
  • the listing is returned as List&lt;String&gt; instead of
    List&lt;File&gt;;
  • the depth level is now an argument supplied to the method (always
    make sure the depth Level is adequate enough to carry out the task);
  • An optional String args argument (named: onlyExtensions) has been
    added to the method so that one (or more) file name extensions can be
    applied to return a list that contains only paths where the file
    names contain the extension(s) applied. If an extension supplied
    happens to be &quot;.jar&quot; then the contents of that JAR file will also
    be applied to the returned List. If nothing is supplied then all
    files are returned in the list.

For JAR files a helper method is also provided:

Modify any of this code as you see fit:

public static List&lt;String&gt; getFilesList(String thePath, int depthLevel, String... onlyExtensions) {
Path p = Paths.get(thePath);
java.util.List&lt;String&gt; FileList = new java.util.ArrayList&lt;&gt;();
try {
java.util.stream.Stream&lt;Path&gt; walk = java.nio.file.Files.walk(p, depthLevel);
for (java.util.Iterator&lt;Path&gt; it = walk.iterator(); it.hasNext();) {
File theFile = it.next().toFile();
if (onlyExtensions.length &gt; 0) {
for (String ext : onlyExtensions) {
ext = ext.trim();
if (!ext.startsWith(&quot;.&quot;)) {
ext = &quot;.&quot; + ext;
}
if (!theFile.isDirectory() &amp;&amp; theFile.getName().substring(theFile.getName().lastIndexOf(&quot;.&quot;)).equalsIgnoreCase(ext)) {
FileList.add(theFile.getName() + &quot; --&gt; &quot; + theFile.getAbsolutePath());
}
else if (!theFile.isDirectory() &amp;&amp; theFile.getName().substring(theFile.getName().lastIndexOf(&quot;.&quot;)).equalsIgnoreCase(&quot;.jar&quot;)) {
List&lt;String&gt; jarList = getFilesNamesFromJAR(theFile.getAbsolutePath());
for (String strg : jarList) {
FileList.add(theFile.getName() + &quot; --&gt; &quot; + strg);
}
}
}
}
else {
FileList.add(theFile.getAbsolutePath());
}
}
}
catch (Exception e) {
System.err.println(e);
}
return FileList;
}

The JAR file helper method:

public static java.util.List&lt;String&gt; getFilesNamesFromJAR(String jarFilePath) {
java.util.List&lt;String&gt; fileNames = new java.util.ArrayList&lt;&gt;();
java.util.zip.ZipInputStream zip = null;
try {
zip = new java.util.zip.ZipInputStream(new java.io.FileInputStream(jarFilePath));
for (java.util.zip.ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
fileNames.add(entry.getName());
}
}
catch (java.io.FileNotFoundException ex) {
System.err.println(ex);
}
catch (java.io.IOException ex) {
System.err.println(ex);
}
finally {
try {
if (zip != null) {
zip.close();
}
}
catch (IOException ex) {
System.err.println(ex);
}
}
return fileNames;
}

To use the getFileList() method you might do something like this:

List&lt;String&gt; fileNames = getFilesList(&quot;C:\\MyDataFolder&quot;, 3, &quot;.cer&quot;, &quot;.jar&quot;);
// Display files in fileNames List
for (String str : fileNames) {
System.out.println(str);
}

huangapple
  • 本文由 发表于 2020年10月12日 01:54:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/64307277.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定