7

我有一个应该从 URL 读取文件的 java 程序(URL 位置是 IIS 网站下的虚拟目录;在下面,在我的初始测试中,我将它视为任何其他文件系统位置)。不幸的是,所有需要读取的文件的路径在其中一个目录名称中都包含一个井号 (#),我无法更改它。当(作为测试)我将它指向路径中没有那个井号的位置时,该程序运行良好。

我首先从传递给程序的字符串创建一个 URL。对于像这样的文件路径/Documents/#2012/09/11(其中 Documents 是 Windows 共享),如果我在命令行上传递这样的路径,我可以让程序成功处理:

file://serverIPaddress/Documents/\%232012/09/07/16/DOC4671179.DOC

也就是说,将井号手动编码为%23,并用反斜杠转义 %23 的 %。

只需一行即可获取该 URL:

URL url = new URL(filePath); // filePath is passed in

但是程序不会像这样用勺子喂食编码路径,所以我必须弄清楚如何以编程方式对井号进行编码。继续在如何对 URL 进行编码以避免 java 中的特殊字符中找到的好建议,我使用多参数构造函数创建了一个 URI(我将传递给程序的参数分解为三个单独的参数以适应这种变化) . 看起来是这样的:

URI uri = new URI(protocol, host, filePath, null); // all values are passed in

正确编码了英镑符号;我的 URI 是:

file://serverIPaddress/Documents/%232012/09/07/16/DOC4671179.DOC

但是如果没有 前面的反斜杠%23,程序会返回Connection refused,大概是因为它在没有反斜杠的情况下误解了路径。

所以我想,好吧,我会自己添加反斜杠。我创建了相同的 URI,提取了它的 rawPath,并通过一些字符串操作,在 %23 前面放了一个反斜杠。然后,我使用该新字符串创建了一个新 URI:

URI uri = new URI(protocol, host, filePath, null); // all values are passed in
String rawPath = uri.getRawPath();
int pctPos = rawPath.indexOf("%");
String escaped = new String("\\");
String firstPart = rawPath.substring(0,pctPos);
String secondPart = rawPath.substring(pctPos);
String newPath = firstPart + escaped + secondPart;
URI uri2 = new URI(protocol, host, newPath, null);

然而,可以预见的是,这给了我一个这样的 URI:

file://<serverIPaddress>/Documents/%5C%25232012/09/07/16/DOC4671179.DOC

同时使用反斜杠和 % 编码。有道理,但在执行时仍然不起作用。

URL API 说:

URL 类本身并不根据 RFC2396 中定义的转义机制对任何 URL 组件进行编码或解码。调用者有责任对任何字段进行编码,这些字段需要在调用 URL 之前进行转义

所以我想,好吧,我不会创建第二个 URI,而是从我在上次尝试中生成的新字符串创建一个 URL:

URI uri = new URI(protocol, host, filePath, null); // all values are passed in
String rawPath = uri.getRawPath();
int pctPos = rawPath.indexOf("%");
String escaped = new String("\\");
String firstPart = rawPath.substring(0,pctPos);
String secondPart = rawPath.substring(pctPos);
String newPath = firstPart + escaped + secondPart;
URL url = new URL(protocol + "://" + host + newPath);

但是在这种方法中,即使我的新路径看起来不错:

/Documents/\%232012/09/07/16/DOC4671179.DOC

生成的 URL 返回为:

file://serverIPAddress/Documents//%232012/09/07/16/DOC4671179.DOC

在 %23 前面有一个额外的正斜杠而不是反斜杠。

有了这个,我已经没有想法了。

  • 是什么让最后一种方法中的反斜杠变成 URL 中的正斜杠?

  • 我能做什么去获取我需要的 URI/URL?

  • 或者我应该问:如果 %23 是合法 URI 或 URL 的一部分,为什么程序首先需要对 %23 中的 % 进行转义,那么我可以对此做些什么吗?

4

1 回答 1

0

不知道为什么需要“\”。它取决于服务器代码。实际上“\”在 URL 中不是合法字符,它应该被编码为 %5C

URI上课很乱。它可能会默默地将文件 URL 的“\”更改为“/”。

试试这个:

    String filePath = "/Documents/#2012/09/11";
    filePath = filePath.replace("#", "\\#");
    URI uri = new URI("file", "serverAddress", filePath, null);

“#”将更改为“%5C%23”。看看它是否有效。

于 2012-09-12T04:40:53.800 回答