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

时间:2011-05-28 21:30:08

标签: java file url path filenames

有没有办法转换它:

/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/myJar.jar

进入这个?:

C:\Users\David\Dropbox\My Programs\Java\Test\bin\myJar.jar

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

fullPath = new String(MainInterface.class.getProtectionDomain()
            .getCodeSource().getLocation().getPath());

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

toString()toExternalForm()都返回:

file:/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/

getPath()返回:

/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/

请注意应转换为空格的%20

有一种快速简便的方法吗?

6 个答案:

答案 0 :(得分:71)

目前的建议(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

关于这些URI的一些观察:

  • URI规范为RFC 1738: URL,由RFC 2396: URI取代,由RFC 3986: URI取代。 (WHATWG也有一个URI spec,但它没有指定文件URI的解释方式。)路径中的任何保留字符均为百分比引用,URI中的非ascii字符是百分比引用的调用URI.toASCIIString()。
  • File.toURI()比Path.toUri()更差,因为File.toURI()returns an unusual non-RFC 1738 URI(给出文件:/而不是file:///)并且不根据UNC路径格式化URI Microsoft’s preferred format。这些UNC URI都不适用于Firefox(Firefox需要文件://///)。
  • 路径比File更严格;您无法从“\.\” prefix构建无效路径。 “这些前缀不会用作路径本身的一部分,”但它们可以传递给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

同样,使用Paths.get(URI)优先于new File(URI),因为Path能够处理UNC URI并拒绝使用\?\前缀的无效路径。但是,如果您不能使用Java 1.7,请改为new File(URI.getSchemeSpecificPart())

顺便说一句,使用URLDecoder解码文件网址。对于包含“+”的文件,例如“file:/// C:/main.c++”,URLDecoder会将其变为“C:\ main.c”! URLDecoder仅用于解析URI查询(param=value&param=value)中的application / x-www-form-urlencoded HTML表单提交,而不是用于解析URI的路径。

2014-09:编辑添加示例。

答案 1 :(得分: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

答案 2 :(得分:3)

如上所述 - getLocation()返回一个URL。文件可以轻松地将URI转换为路径,所以对我来说最简单的方法就是使用:

File fullPath = new File(MainInterface.class.getProtectionDomain().
    getCodeSource().getLocation().toURI());

当然,如果你真的需要String,只需修改为:

String fullPath = new File(MainInterface.class.getProtectionDomain().
    getCodeSource().getLocation().toURI()).toString();

根本不需要URLDecoder。

答案 3 :(得分:2)

以下代码是您所需要的:

String path = URLDecoder.decode("/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/", "UTF-8");
System.out.println(new File(path).getPath());

答案 4 :(得分:2)

目前的答案对我来说似乎很可疑。

java.net.URL.getFile

转换文件网址,例如

java.net.URL = file:/C:/some/resource.txt

进入这个

java.lang.String = /C:/some/resource.txt

所以你可以使用这个构造函数

new File(url.getFile)

为您提供Windows路径

java.io.File = C:\some\resource.txt

答案 5 :(得分:2)

你好混淆未来的人。这里的文件路径配置有细微差别。您为TESSDATA_PREFIX设置的路径由C ++ tesseract程序在内部使用,java包装器。这意味着如果您正在使用窗口,则需要替换前导斜杠并用反斜杠替换所有其他正斜杠。一个非常hacky的解决方案看起来像这样:

URL pathUrl = this.getClass().getResource(TESS_DATA_PATH);
String pathStr = pathUrl.getPath();

// hack to get around windows using \ instead of /
if (SystemUtils.IS_OS_WINDOWS) {
  pathStr = pathStr.substring(1);
  pathStr = pathStr.replaceAll("/", "\\\\");
}