简体   繁体   English

如何解决java.io.IOException:在java.io.FileInputStream.read(本机方法)处读取错误?

[英]How to resolve java.io.IOException: Read error at java.io.FileInputStream.read(Native Method)?

I'm getting the following error, 我收到以下错误,

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)  

Here is my code: 这是我的代码:

    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();
            }
    }

}

The process I have to do is: 我要做的过程是:

1) reading the file from the source location.. ( here I am using main() just for testing purpose) 1)从源位置读取文件..(这里我仅使用main()进行测试)

2) deleting the <Tax> and </Tax> nodes in the source file. 2)删除源文件中的<Tax></Tax>节点。

3) writng the file to target location. 3)将文件写入目标位置。

XML FIle: XML文件:

<!-- 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>

please tell me the way to resolve this issue.. 请告诉我解决此问题的方法。

Thanks in advance.. 提前致谢..

UPDATED According to the new requirement: 更新根据新要求:

You need to parse your XML document and get all those "Tax" tags. 您需要解析XML文档并获取所有这些“税”标签。 Then you need to collect their child elements and append them to the Tax' parent. 然后,您需要收集其子元素并将其附加到Tax的父元素。 Then, delete the Tax tag. 然后,删除“税收”标签。 This should look like the following (tested with your given document): 外观应如下所示(已通过给定文档进行了测试):

    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();
    }
}

You only need to put the <?xml ... ?> at the beginning of the input XML document. 您只需要在输入XML文档的开头放置<?xml ... ?> Otherwise you will get an Error: The processing instruction target matching “[xX][mM][lL]” is not allowed . 否则会出现Error: The processing instruction target matching “[xX][mM][lL]” is not allowed


OLD: 旧:

The BufferedReader that is taking your InputStream in execute method is the problem, when you're closing it (lines 69,70). 当您关闭InputStreamBufferedReader ,它是问题所在(第69,70行)。

Do not call close() on the BufferedReader , because it will close all system handles and files underneath it (see Javadoc for BufferedReader close() method ). 不要在BufferedReader上调用close() ,因为它会关闭其下的所有系统句柄和文件(请参阅Javadoc中的BufferedReader close()方法 )。

Same applies for the OutputStreamWriter . 同样适用于OutputStreamWriter

Instead of reader.close() you should call reader.reset() . 而不是reader.close() ,应该调用reader.reset() This is because you already read the file and there is an internal cursor which points to the last read location and will you give you the next following data upon new read requests and moves itself forwards. 这是因为您已经读取了文件,并且有一个内部游标指向最后的读取位置,并且将根据新的读取请求为您提供下一个后续数据,并将其向前移动。

You don't need the writeOutputfile method as you are already writing the new XML. 您已经在编写新的XML,因此不需要writeOutputfile方法。 Just remove the method and update your execute method like this: 只需删除方法并更新您的execute方法,如下所示:

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();    
    }   
}

EDIT: You can also parse the source file with the DOM parser, manipulate the DOM and write it back to a new file: 编辑:您还可以使用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.java2s.com/教程/Java/0440__XML/thevelement.html

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

EDIT2: Using InputStream and OutputStream (example) ... 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);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM