如何解决java.io.IOException:在java.io.FileInputStream.read(Native Method)中读取错误?

时间:2015-04-13 07:23:23

标签: java xml

我收到以下错误,

java.io.IOException: Read error  
at java.io.FileInputStream.read(Native Method) at      
com.sun.org.apache.xerces.internal.impl.XMLEntityManager$RewindableInputStream.read(Unknown Source) 
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity  
(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion (Unknown Source)
       at    com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at   com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)  
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)  
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)  
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)  
at com.example.TestIntegrate.execute(TestIntegrate.java:71)  
at com.example.TestIntegrate.main(TestIntegrate.java:42)  

这是我的代码:

    public class TestIntegrate {

    private Document doc = null;
    public static void main(String[] args) {
        FileInputStream fin;
        try {
            fin = new FileInputStream("C:/Users/xyz/workspace/TEST_2.xml");
            FileOutputStream fout = new FileOutputStream("C:/Users/xyz/workspace/OutputFile.xml");      
            TestIntegrate t = new TestIntegrate();
            t.execute(fin, fout);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public void execute(InputStream sourceFile, OutputStream targetFile) //throws StreamTransformationException
    {       
        BufferedReader reader;
        OutputStreamWriter writer;
        try{    

            // creating the parser object 
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            String line = "<Tax>";
            String line1 = "</Tax>";
            String currentLine;
            reader = new BufferedReader(new InputStreamReader(sourceFile));
            writer =new OutputStreamWriter(targetFile);

            dbFactory.setNamespaceAware(true);
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            while ( (currentLine = reader.readLine() ) != null){
                  String trimmedLine = currentLine.trim();
                  if(trimmedLine.equals(line) || trimmedLine.equals(line1) ) continue;
                  writer.write(currentLine + System.getProperty("line.separator"));
            }
            reader.close();
            writer.close();
            doc = dBuilder.parse(sourceFile);
            writeOutputfile(doc,targetFile);   
        } catch (Exception e) { 
            e.printStackTrace();    
        }   
    }
    private void writeOutputfile(Document doc,OutputStream targetFile) { 
            try {

                TransformerFactory transformFactory = TransformerFactory.newInstance();
                DOMSource source = new DOMSource(doc);
                Transformer transformer;
                transformer = transformFactory.newTransformer();
                Writer outWriter = new StringWriter();   
                StreamResult result = new StreamResult(targetFile);   
                transformer.transform(source,result);
            }
                 catch (TransformerException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            }
    }

}

流程我必须做的是:

1)从源位置读取文件..(这里我使用main()仅用于测试目的)

2)删除源文件中的<Tax></Tax>节点。

3)将文件写入目标位置。

XML FIle:

<!-- language: lang-xml -->

<?xml version="1.0" encoding="UTF-8"?>
<School>
    <SSLC>
        <name />
        <rollno />
    </SSLC>
    <Tax>
        <first_pu>
            <name />
            <rollno />
        </first_pu>
        <second_pu>
            <name />
            <rollno />
        </second_pu>
    </Tax>
    <Tax>
        <first_pu>
            <name />
            <rollno />
        </first_pu>
        <second_pu>
            <name />
            <rollno />
        </second_pu>
    </Tax>
    <Tax>
        <first_pu>
            <name />
            <rollno />
        </first_pu>
        <second_pu>
            <name />
            <rollno />
        </second_pu>
    </Tax>
</School>

请告诉我解决此问题的方法..

提前致谢..

2 个答案:

答案 0 :(得分:2)

更新根据新要求:

您需要解析XML文档并获取所有这些&#34; Tax&#34;标签。然后你需要收集他们的子元素并将它们附加到Tax&#39;家长。然后,删除Tax标签。这应该如下所示(使用您的给定文档进行测试):

    public static void execute(InputStream in, OutputStream out) {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    Document doc = null;
    try {
        doc = factory.newDocumentBuilder().parse(in);
    } catch (SAXException | IOException | ParserConfigurationException e) {
        e.printStackTrace();
    }
    NodeList nodes = doc.getElementsByTagName("Tax");
    List<Node> nodesToRemove = new LinkedList<>();
    for (int i = 0; i < nodes.getLength(); i++) {
        Node node = nodes.item(i);
        nodesToRemove.add(node);

        List<Node> nodesToMove = new LinkedList<>();
        for (int j = 0; j < node.getChildNodes().getLength(); j++) {
            nodesToMove.add(node.getChildNodes().item(j));
        }

        for (Node childNode : nodesToMove) {
            node.removeChild(childNode);
            node.getParentNode().appendChild(childNode);
        }
    }

    for (Node n : nodesToRemove) {
        n.getParentNode().removeChild(n);
    }

    doc.normalize();

    Transformer tf = null;
    try {
        tf = TransformerFactory.newInstance().newTransformer();
    } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) {
        e.printStackTrace();
    }
    tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    tf.setOutputProperty(OutputKeys.INDENT, "yes");
    tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
    try {
        tf.transform(new DOMSource(doc), new StreamResult(out));
    } catch (TransformerException e) {
        e.printStackTrace();
    }
}

您只需将<?xml ... ?>放在输入XML文档的开头即可。否则,您将获得Error: The processing instruction target matching “[xX][mM][lL]” is not allowed


<强> OLD:

当您关闭它时,BufferedReader执行方法中的InputStream是问题所在(第69,70行)。

请勿在{{1​​}}上致电close(),因为它会关闭其下方的所有系统句柄和文件(请参阅Javadoc for BufferedReader close() method)。

同样适用于BufferedReader

而不是OutputStreamWriter,您应该致电reader.close()。这是因为您已经读取了该文件,并且有一个内部光标指向最后一个读取位置,您将在新读取请求时向您提供下一个数据并向前移动。

答案 1 :(得分:0)

您不需要writeOutputfile方法,因为您已经在编写新的XML。只需删除方法并更新您的执行方法,如下所示:

public void execute(InputStream sourceFile, OutputStream targetFile) //throws StreamTransformationException
{       
    BufferedReader reader;
    OutputStreamWriter writer;
    try{    

        // creating the parser object 
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        String line = "<Tax>";
        String line1 = "</Tax>";
        String currentLine;
        reader = new BufferedReader(new InputStreamReader(sourceFile));
        writer =new OutputStreamWriter(targetFile);

        dbFactory.setNamespaceAware(true);
        while ( (currentLine = reader.readLine() ) != null){
              String trimmedLine = currentLine.trim();
              if(trimmedLine.equals(line) || trimmedLine.equals(line1) ) continue;
              writer.write(currentLine + System.getProperty("line.separator"));
        }

        reader.close();
        writer.close();
    } catch (Exception e) { 
        e.printStackTrace();    
    }   
}

修改 您还可以使用DOM解析器解析源文件,操作DOM并将其写回新文件:

public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, TransformerException {
    try { 
        TestIntegrate t = new TestIntegrate();
        t.execute("C:/Users/xyz/workspace/TEST_2.xml", "C:/Users/xyz/workspace/OutputFile.xml");
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}


public void execute(String sourceFile, String targetFile) throws ParserConfigurationException, SAXException, IOException, TransformerException
{
    //Parse the source xml file
    File source = new File(sourceFile);
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document doc = dBuilder.parse(source);
    doc.getDocumentElement().normalize();

    NodeList taxNodes = doc.getElementsByTagName("Tax");

    //Loop through tax nodes and move inner nodes => start at the end as we remove the tax nodes afterwards
    for(int i = taxNodes.getLength() - 1; i > -1; i--)
    {
        Element taxNode = (Element) taxNodes.item(i);
        Node parent = taxNode.getParentNode();

        while (taxNode.hasChildNodes()) 
        {
            parent.insertBefore(taxNode.getFirstChild(), taxNode);
        }

        taxNodes.item(i).getParentNode().removeChild(taxNodes.item(i));
    }

    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    DOMSource domSource = new DOMSource(doc);
    StreamResult result = new StreamResult(new File(targetFile));
    transformer.transform(domSource, result);

}

http://www.java2s.com/Tutorial/Java/0440__XML/Moveallchildrenoftheelementinfrontoftheelement.htm

http://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/

<强> EDIT2: 使用InputStream和OutputStream(示例)...

public void execute(InputStream sourceFile, OutputStream targetFile) throws StreamTransformationException
{
    //Parse the source xml file
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = null;
    try
    {
        dBuilder = dbFactory.newDocumentBuilder();
    } 
    catch (ParserConfigurationException e)
    {
        throw new StreamTransformationException(e);
    }
    Document doc = null;
    try
    {
        doc = dBuilder.parse(sourceFile);
    }
    catch (SAXException e) 
    {
        throw new StreamTransformationException(e);
    } 
    catch (IOException e) 
    {
        throw new StreamTransformationException(e);
    }
    doc.getDocumentElement().normalize();

    NodeList taxNodes = doc.getElementsByTagName("Tax");

    //Loop through tax nodes and move inner nodes => start at the end as we remove the tax nodes afterwards
    for(int i = taxNodes.getLength() - 1; i > -1; i--)
    {
        Element taxNode = (Element) taxNodes.item(i);
        Node parent = taxNode.getParentNode();

        while (taxNode.hasChildNodes()) 
        {
            parent.insertBefore(taxNode.getFirstChild(), taxNode);
        }

        taxNodes.item(i).getParentNode().removeChild(taxNodes.item(i));
    }

    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = null;
    try
    {
        transformer = transformerFactory.newTransformer();
    }
    catch (TransformerConfigurationException e)
    {
        throw new StreamTransformationException(e);
    }
    DOMSource domSource = new DOMSource(doc);
    StreamResult result = new StreamResult(targetFile);
    try
    {
        transformer.transform(domSource, result);
    } 
    catch (TransformerException e)
    {
        throw new StreamTransformationException(e);
    }

}