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

时间:2013-12-06 22:13:35

标签: java xml urlencode filepath

这是一个写出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.<init>(FileOutputStream.java:179)
    at java.io.FileOutputStream.<init>(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)

3 个答案:

答案 0 :(得分:10)

尝试更改此行:

StreamResult result = new StreamResult(xmlFile);

进入这个:

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

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

答案 1 :(得分:2)

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

来自Oracle docs

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路径,因此大概{@ 1}}决定主动对其进行自动编码,而不是假设它是“符合URI语法的字符串” ”

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

答案 2 :(得分:2)

在包含特殊字符的路径的情况下也可能出现此问题,对于这些路径,第一个答案几乎没有帮助(转换就是这样)。 例如,在我的情况下,我的文件的路径包含char&#34;`&#34;这被自动翻译成&#34;%60&#34;。

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

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编码问题。