我有一个java程序应该从URL读取文件(URL位置是IIS网站下的虚拟目录;下面,在我的初始测试中,我将其视为任何其他文件系统地点)。不幸的是,所有需要读取的文件的路径都包含一个目录名中的井号(#),而我无法改变它。当(作为测试)我将它指向一个在路径中没有英镑符号的位置时,该程序可以很好地工作。
我首先从传递给程序的字符串创建URL。对于像/Documents/#2012/09/11
这样的文件路径(其中Documents是Windows共享),如果我在命令行上传递了这样的路径,我可以让程序成功处理:
file://serverIPaddress/Documents/\%232012/09/07/16/DOC4671179.DOC
也就是说,将井号手动编码为%23
,并使用反斜杠转义%23的%。
只有一行来获取该网址:
URL url = new URL(filePath); // filePath is passed in
但是这个程序并不是像这样编码的路径,所以我必须弄清楚如何以编程方式对英镑符号进行编码。继续在how to encode URL to avoid special characters in 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
同时使用反斜杠和%编码。有道理,但在执行时仍然不起作用。
网址API说:
URL类本身不会对任何URL组件进行编码或解码 根据RFC2396中定义的转义机制。它是 调用者负责编码需要的任何字段 在调用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中的%才能首先进行转义,如果%23是合法URI或URL的一部分,那么我可以做些什么那样做呢?
答案 0 :(得分:0)
不确定为什么需要“\”。这取决于服务器代码。实际上“\”不是URL中的合法字符,它应该编码为%5C
URI
课非常混乱。对于文件URL,它可以默默地将“\”更改为“/”。
请改为尝试:
String filePath = "/Documents/#2012/09/11";
filePath = filePath.replace("#", "\\#");
URI uri = new URI("file", "serverAddress", filePath, null);
“#”将更改为“%5C%23”。看看它是否有效。