将 URL 转换为普通的 windows 文件名 Java
Posted
技术标签:
【中文标题】将 URL 转换为普通的 windows 文件名 Java【英文标题】:Convert URL to normal windows filename Java 【发布时间】:2011-09-04 02:24:53 【问题描述】:有没有办法转换这个:
/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
应该转换为空格。
有没有一种快速简便的方法来做到这一点?
【问题讨论】:
好吧,我尝试对空格使用查找和替换并删除第一个字符,但我不太喜欢它。这就是为什么我在这里问的原因,也许有人知道某种方法可以以一种不易出错且更有效的方式进行转换。 对获取 jar 文件的完整文件名的任何替代方法也表示赞赏。 @David 你的意思是 String WinPath = System.getenv("USERPROFILE"); WinPath = WinPath.replace("\\", "\\\\"); WinPath += "\\\\Desktop\\\\SalesReports\\\\"; 【参考方案1】: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
【讨论】:
这个答案很危险。向下滚动到@yonran 的答案 你的意思是向上滚动【参考方案2】:下面的代码就是你需要的:
String path = URLDecoder.decode("/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/", "UTF-8");
System.out.println(new File(path).getPath());
【讨论】:
谢谢。这与 .getAbsolutePath() 是完美的。 URLDecoder 类型的 decode(String) 方法已弃用。使用 new File() 更好 @David 你仍然需要解码。只需使用正确的参数(如我的回答所示) 我已经用 getPath 更新了答案,它永远不会抛出异常,并更改了解码方法以指定编码(不推荐使用该变体)。【参考方案3】:目前的答案对我来说似乎很可疑。
java.net.URL.getFile
转成这样的文件 URL
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
【讨论】:
这是不正确的。它不能解决不正确的 (%20) 空格表示。我猜那些投票的人就像答案作者;没有阅读问题。【参考方案4】:目前的建议(JDK 1.7+)是转换 URL → URI → Path。因此,要将 URL 转换为文件,您会说 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 时,URI 中的非 ascii 字符用百分号引用.toASCIIString()。 File.toURI() 比 Path.toUri() 差,因为 File.toURI() returns an unusual non-RFC 1738 URI(给出 file:/ 而不是 file:///)并且不根据 @987654326 格式化 UNC 路径的 URI @。但是,这些 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
来解码文件URL。对于包含“+”的文件,例如“file:///C:/main.c++”,URLDecoder
会将其转换为“C:\main.c ”! URLDecoder
仅用于解析 URI 查询 (param=value&param=value
) 中的 application/x-www-form-urlencoded html 表单提交,而不是取消引用 URI 的路径。
2014-09:编辑以添加示例。
【讨论】:
当然这一切都会引发该死的 URISyntaxException。 Paths.get() 使用默认文件系统,因此如果您使用它,您将无法使用内存文件系统测试您的代码【参考方案5】:如前所述 - getLocation() 返回一个 URL。 File 可以轻松地将 URI 转换为路径,所以对我来说最简单的方法就是使用:
File fullPath = new File(MainInterface.class.getProtectionDomain().
getCodeSource().getLocation().toURI());
当然如果你真的需要String,修改为:
String fullPath = new File(MainInterface.class.getProtectionDomain().
getCodeSource().getLocation().toURI()).toString();
你根本不需要 URLDecoder。
【讨论】:
这比其他答案简单得多,实际上对我有用。【参考方案6】:你好,来自未来的困惑的人们。这里的文件路径配置有细微差别。您为 TESSDATA_PREFIX 设置的路径由 C++ tesseract 程序在内部使用,not 由 java 包装器使用。这意味着,如果您使用的是 Windows,则需要替换前导斜杠并将所有其他正斜杠替换为反斜杠。一个非常 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("/", "\\\\");
【讨论】:
以上是关于将 URL 转换为普通的 windows 文件名 Java的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Windows 路径转换为文件:URL,在批处理文件中,适合 SVN 命令行使用