将URL转换为普通的Windows文件名Java

Dav*_*vid 56 java url filenames file path

有没有办法转换这个:

/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/myJar.jar
Run Code Online (Sandbox Code Playgroud)

进入这个?:

C:\Users\David\Dropbox\My Programs\Java\Test\bin\myJar.jar
Run Code Online (Sandbox Code Playgroud)

我使用以下代码,它将返回.JAR存档的完整路径或/ bin目录.

fullPath = new String(MainInterface.class.getProtectionDomain()
            .getCodeSource().getLocation().getPath());
Run Code Online (Sandbox Code Playgroud)

问题是,getLocation()返回一个URL,我需要一个正常的Windows文件名.我尝试过以后添加以下内容getLocation():

toString()并且toExternalForm()都返回:

file:/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/
Run Code Online (Sandbox Code Playgroud)

getPath() 收益:

/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/
Run Code Online (Sandbox Code Playgroud)

请注意%20哪些应转换为空格.

有这么简单快捷的方法吗?

yon*_*ran 77

目前的建议(JDK 1.7+)是转换URL→URI→路径.因此,要将URL转换为File,您会说Paths.get(url.toURI()).toFile().如果你还不能使用JDK 1.7,我会推荐new File(URI.getSchemeSpecificPart()).

转换文件→URI:首先,我将向您展示一些您可能在Java中获得的URI的示例.

                          -classpath URLClassLoader File.toURI()                Path.toUri()
C:\Program Files          file:/C:/Program%20Files/ file:/C:/Program%20Files/   file:///C:/Program%20Files/
C:\main.c++               file:/C:/main.c++         file:/C:/main.c++           file:///C:/main.c++
\\VBOXSVR\Downloads       file://VBOXSVR/Downloads/ file:////VBOXSVR/Downloads/ file://VBOXSVR/Downloads/
C:\Résume.txt             file:/C:/R%c3%a9sume.txt  file:/C:/Résume.txt         file:///C:/Résume.txt
\\?\C:\Windows (non-path) file://%3f/C:/Windows/    file:////%3F/C:/Windows/    InvalidPathException
Run Code Online (Sandbox Code Playgroud)

关于这些URI的一些观察:

  • URI规范是 RFC 1738:URL,由RFC 2396:URI取代,由RFC 3986:URI取代.(WHATWG也有一个URI规范,但它没有指定应该如何解释文件URI.)路径中的任何保留字符都是百分比引用的,并且当您调用URI时,URI中的非ascii字符是百分比引用的. toASCIIString().
  • File.toURI()比Path.toUri()更糟糕,因为File.toURI()返回一个不寻常的非RFC 1738 URI(给出文件:/而不是file:///),并且不根据UNC路径格式化URI.微软的首选格式.这些UNC URI都不适用于Firefox(Firefox需要file://///).
  • 路径比File更严格; 你不能从"\.\"前缀构造一个无效的路径."这些前缀不会用作路径本身的一部分,"但它们可以传递给Win32 API.

转换URI→文件:让我们尝试将前面的示例转换为文件:

                            new File(URI)            Paths.get(URI)           new File(URI.getSchemeSpecificPart())
file:///C:/Program%20Files  C:\Program Files         C:\Program Files         C:\Program Files
file:/C:/Program%20Files    C:\Program Files         C:\Program Files         C:\Program Files
file:///C:/main.c++         C:\main.c++              C:\main.c++              C:\main.c++
file://VBOXSVR/Downloads/   IllegalArgumentException \\VBOXSVR\Downloads\     \\VBOXSVR\Downloads
file:////VBOXSVR/Downloads/ \\VBOXSVR\Downloads      \\VBOXSVR\Downloads\     \\VBOXSVR\Downloads
file://///VBOXSVR/Downloads \\VBOXSVR\Downloads      \\VBOXSVR\Downloads\     \\VBOXSVR\Downloads
file://%3f/C:/Windows/      IllegalArgumentException IllegalArgumentException \\?\C:\Windows
file:////%3F/C:/Windows/    \\?\C:\Windows           InvalidPathException     \\?\C:\Windows
Run Code Online (Sandbox Code Playgroud)

同样,Paths.get(URI)优先使用new File(URI),因为Path能够处理UNC URI并拒绝带有\?\前缀的无效路径.但是如果你不能使用Java 1.7,那就说吧new File(URI.getSchemeSpecificPart()).

顺便说一句,千万不能URLDecoder解码文件URL.对于包含"+"的文件,例如"file:/// C:/main.c++", URLDecoder将其转换为"C:\ main.c"!URLDecoder仅用于解析URI的query(param=value&param=value)中的application/x-www-form-urlencoded HTML表单提交,而不是用于解析URI的路径.

2014-09:编辑添加示例.

  • 当然这一切都引发了一场该死的URISyntax异常. (3认同)

Boz*_*zho 17

String path = "/c:/foo%20bar/baz.jpg";
path = URLDecoder.decode(path, "utf-8");
path = new File(path).getPath();
System.out.println(path); // prints: c:\foo bar\baz.jpg
Run Code Online (Sandbox Code Playgroud)

  • 你的意思是向上滚动 (3认同)