Java附带的Transformer库将文件路径中的空格转换为%20

这是一个写出XML文件的测试应用程序。

为什么路径中的空格被转换为%20

 public class XmlTest { public static void main(String[] args) { String filename = "C:\\New Folder\\test.xml"; try { DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); Document doc = docBuilder.newDocument(); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); DOMSource source = new DOMSource(doc); File xmlFile = new File(filename); if (xmlFile.exists()) { xmlFile.delete(); } StreamResult result = new StreamResult(xmlFile); transformer.transform(source, result); } catch (ParserConfigurationException ex) { ex.printStackTrace(); } catch (TransformerException tfe) { tfe.printStackTrace(); } } } 

堆栈跟踪:

 java.io.FileNotFoundException: C:\New%20Folder\test.xml (The system cannot find the path specified) at java.io.FileOutputStream.open(Native Method) at java.io.FileOutputStream.(FileOutputStream.java:179) at java.io.FileOutputStream.(FileOutputStream.java:70) at org.apache.xalan.transformer.TransformerIdentityImpl.createResultContentHandler(TransformerIdentityImpl.java:287) at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:330) at avm.trans.xml.XmlTest.main(XmlTest.java:52) 

尝试更改此行:

 StreamResult result = new StreamResult(xmlFile); 

进入这个:

 StreamResult result = new StreamResult(new FileOutputStream(xmlFile)); 

我不知道,为什么文件名作为URL处理。

根据@ChristianKuetbach的回答,似乎传递给StreamResult构造函数的参数决定了它将如何处理。

来自Oracle文档

 public StreamResult(String systemId) Construct a StreamResult from a URL. Parameters: systemId - Must be a String that conforms to the URI syntax. public StreamResult(File f) Construct a StreamResult from a File. Parameters: f - Must a non-null File reference. 

所以最初,我传递了一个String路径,因此大概是StreamResult决定主动自动编码,而不是假设它是“一个符合URI语法的字符串”。

因此,传入File对象会告诉它将其作为文件路径而不是URL处理,因此空格(和其他特殊字符)不会被编码。

在包含特殊字符的路径的情况下也可能出现此问题,对此第一个答案几乎没有帮助(转换,即)。 例如,在我的情况下,我的文件路径包含自动转换为“%60”的字符“`”。

我通过更改代码行解决了我的问题:

 StreamResult result = new StreamResult(xmlFile); 

result = D:/ Work /…/%60Projects /…/ xmlFile.xml

进入代码行:

 StreamResult result = new StreamResult(xmlFile); result.setSystemId(URLDecoder.decode(xmlFile.toURI().toURL().toString(), "UTF-8")); 

result = D:/ Work /…/`Projects /…/ xmlFile.xml

这将覆盖StreamResult类中默认实现的URL编码问题。