Java.nio.file.InvalidPathException: 索引为2的字符<:>是非法字符。

55

我需要将一个类路径资源从一个包复制到另一个包。

我的程序是:

    public static void main(String[] args) throws IOException, URISyntaxException {

            ClassLoader classLoader = CopyFileToDirectoryTest.class.getClassLoader();
InputStream in = classLoader.getResourceAsStream("com/stackoverflow/main/Movie.class");

            URI uri = ClassLoader.getSystemResource("com/stackoverflow/json").toURI();
            Path path = Paths.get(uri.getPath(),"Movie.class");
            System.out.println(path);

            long copy = Files.copy(in, path, StandardCopyOption.REPLACE_EXISTING);
            System.out.println(copy);

        }

Files.copy方法中,我遇到了异常:

Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <:> at index 2: /D:/Programs/workspaceEE/HibernateDemo/target/classes/com/stackoverflow/json
    at sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
    at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
    at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
    at sun.nio.fs.WindowsPath.parse(WindowsPath.java:94)
    at sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:255)
    at java.nio.file.Paths.get(Paths.java:84)
    at com.stackoverflow.main.CopyFileToDirectoryTest.main(CopyFileToDirectoryTest.java:34)

如何解决它?

解决方案

public static void main(String[] args) throws IOException, URISyntaxException {
        ClassLoader classLoader = CopyFileToDirectoryTest.class.getClassLoader();
        InputStream in = classLoader.getResourceAsStream("com//stackoverflow//main//Movie.class");
        URI uri = ClassLoader.getSystemResource("com//stackoverflow//json").toURI();
        String mainPath = Paths.get(uri).toString();
        Path path = Paths.get(mainPath, "Movie.class");
        System.out.println(path);
        long copy = Files.copy(in, path, StandardCopyOption.REPLACE_EXISTING);
        System.out.println(copy);
    }

这段代码可以正确将来自包com/stackoverflow/mainMovie.class 复制到 com/stackoverflow/json 包中。


2
这个不可行是因为你的类路径由透明和不透明资源组成 - 比如那些在 jar 内部的资源。你试图写入一个看起来像 jar:file:/com/stackoverflow/json 的路径,这是无效的 PathFile,但是是一个有效的 URI。一般来说,你不能写入类路径,只能从它读取。 - Boris the Spider
没有JAR文件,这是Maven项目。 - Jay Smith
当你编译一个Maven项目时,它会生成一个jar文件。在Java 9之前,你还有什么其他方式来分发你的编译代码呢? - Boris the Spider
这个回答解决了你的问题吗?Java NIO文件路径问题 - Pino
8个回答

69
问题是Paths.get()不期望从uri.getPath()生成的那种值。
解决方案:
URI uri = ClassLoader.getSystemResource("com/stackoverflow/json").toURI();
String mainPath = Paths.get(uri).toString();
Path path = Paths.get(mainPath ,"Movie.class");

10

试试这个:

Path path = new File(getClass()
.getResource("/<path to the image in your build/classes folder>")
.getFile()).toPath();

获取正确的路径。在几个小时内尝试找出为什么无法从jar文件获取文件后,这对我有用了。这适用于NetBeans 8.02。


5

我曾经遇到相同的问题并得到了异常提示,注意到文件名中有一个空格,所以我必须将其删除。之后,问题得到了解决。

Path filePath = Paths.get(dirPathStr, newFileName.trim());

3

尝试了很多次,这个方法对我有用

      Path path = new File(getClass().getResource("/data.json").getFile()).toPath(); 

现在你可以随意使用你的路径,例如:
        Reader reader = Files.newBufferedReader(path);

2
我遇到了与原回答相同的问题,这个问题已经困扰我两天了,最后我找到了解决方法。 空格是导致这种问题的原因。 尝试解决。原始回答: "最初的回答"。
var fileName=YourFileName.trim();
Path filePath = Paths.get(dirPathStr, fileName);

1

我遇到了同样的错误

./gradlew build

2023-04-10T16:56:54.855+02:00 INFO 10476 --- [ main] c.v.s.d.m.a.VogellaApplication : 没有设置活动配置文件,回退到默认配置文件:"default" 主线程异常 java.nio.file.InvalidPathException: 索引27处存在尾随字符 < >:com.vogella.spring.di.model at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:191) at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153) at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77) at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)

我分析了文件名和配置。我注意到在build.gradle文件的'group'属性中有一个空格。

group = 'com.vogella.spring.di.model '

我去掉了多余的空格,构建命令正常工作了。


0

在我的自动化过程中,我使用 extentReports 时遇到了同样的问题,我只是简单地更正了报告路径。

public void config() {
    String path = System.getProperty("user.dir")+"\\reports\\index.html";       
    ExtentSparkReporter reporter = new ExtentSparkReporter(path);
    reporter.config().setReportName("Web Automation Reports");
    reporter.config().setDocumentTitle("Web Results");

...


0
以下解决方案可以正确运行:
解决方案1:
String logFileLocalPath = "../log/log.txt";
File logFile = new File(getURL(logFileLocalPath).getPath());

解决方案2:

File logFile = new 
File(Paths.get(getURL(logFileLocalPath).toURI()).toString());

private static URL getURL(String localPath) {

      return Main.class.getResource(localPath);
}

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