将URL转换为正常的Windows文件名Java

有没有办法来转换这个:

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

进入这个吗?

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

我正在使用下面的代码,它将返回.JAR归档或/ bin目录的完整path。

 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

有没有一个简单快捷的方法呢?

目前的build议(使用JDK 1.7+)是转换URL→URI→path。 所以要将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规范 ,但是它没有指定应该如何解释文件URI。)在调用URI时,path中的任何保留字符都是百分比引号,URI中的非ascii字符是百分比引号。 toASCIIString()。
  • File.toURI()比Path.toUri()更糟,因为File.toURI() 返回一个不寻常的非RFC 1738 URI (给出file:/而不是file:///),并且不根据微软的首选格式 。 这些UNC URI在Firefox中都不起作用(Firefox需要file://///)。
  • path比File更严格; 你不能从“\。\”前缀构造一个无效的path。 “这些前缀不被用作path本身的一部分,”但它们可以传递给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并使用\?\前缀拒绝无效path。 但是,如果您不能使用Java 1.7,请改为使用new File(URI.getSchemeSpecificPart())

顺便说一句,不要使用URLDecoder来解码文件的URL。 对于包含“+”的文件,比如“file:/// C:/main.c++”, URLDecoder会将它变成“C:\ main.c”! URLDecoder仅用于parsingURI查询( param=value&param=value )中的application / x-www-form-urlencoded HTML表单提交,而不用于查询URI的path。

2014-09:编辑添加示例。

 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 

目前的答案似乎对我很腥。

 java.net.URL.getFile 

变成这样的文件URL

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

进入这个

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

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

 new File(url.getFile) 

给你的Windowspath

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

下面的代码是你需要的:

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

如前所述 – getLocation()返回一个URL。 文件可以很容易地将URI转换为path,所以对我来说最简单的方法就是使用:

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

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

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

你根本不需要URLDecoder。

你好,来自未来的困惑的人。 这里的文件pathconfiguration有一个细微差别。 您为TESSDATA_PREFIX设置的path由C ++ tesseract程序内部使用, 而不是由java包装程序使用。 这意味着如果您使用的是Windows,则需要replace前面的斜杠,并用反斜杠replace所有其他正斜杠。 一个非常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("/", "\\\\"); }