首页 > 解决方案 > 如何在 XML 文件中写入可序列化对象而不覆盖文件?SAXParseException

问题描述

正如标题所示,我想将对象写入文件而不覆盖同一个文件。问题是,当我尝试将对象写入文件时,我收到以下消息:

“org.xml.sax.SAXParseException;lineNumber:1;columnNumber:1;文件过早结束。继续……”

然后没有任何东西进入文件。如果我尝试在其他类型的文件(如 .ser)中进行可序列化,我会收到一条错误消息,指出无法写入文件。

package application.library.crud.kvlth;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;

public class Create {
    private static XMLEncoder output;
    private static XMLDecoder inpt;
    public static void main(String[] args) throws IOException {
        openFile();
        addRecords();
        closeFile();
    }

    public static void openFile() {
            try {
                output = new XMLEncoder(
                        new BufferedOutputStream(
                                new FileOutputStream("library.xml")));

            } catch (IOException ioException) {
                System.err.println("Error opening file. Terminating.");
                System.exit(1);
            }

    }

    public static void addRecords() throws IOException {
        inpt = new XMLDecoder(
                new BufferedInputStream(
                        new FileInputStream("library.xml")));

        ArrayList<Book> books;

        Scanner input = new Scanner(System.in);

        System.out.printf("%s%n%s%n? ",
                "Enter ISBN number, Author's name, Book's Title.",
                "Enter end-of-file indicator to end input.");

        while (input.hasNext()) {

            try {
                Book record = new Book(input.nextLine(),
                        input.nextLine(), input.nextLine());

                books = (ArrayList<Book>) inpt.readObject(); /*here 
                at my IDE (Intellij) it shows me the following 
                message: "Unchecked cast: 'java.lang.Object' to 
               'java.util.ArrayList'"*/
                inpt.close();
                books.add(record);
                output.writeObject(books);

            } catch (NullPointerException e){
                e.getStackTrace();

            } catch (ArrayIndexOutOfBoundsException arrayExc){

            }
            System.out.println("? ");
        }
    }

    public static void closeFile() {
        if (output != null)
            output.close();
    }
}

这就是它向我展示的。它继续运行,但从不写入文件。

标签: javaxmlparsing

解决方案


没有办法write objects to the file without overwrite the same file。如果要读取文件,请在中间插入一些元素,然后输出文件的其余部分,您要么必须在内存中读取它,然后再将其全部写出,要么写入您正在执行插入的临时文件和然后将临时文件复制到原始文件上。

因此,在您的情况下,将您的“输出”文件更改为临时文件,然后在完成输出后将其复制回原始文件。

流式处理示例: 例如,如果您的输入是 input.xml:

<books>
    <Book>Genesis</Book>
    <Bool>Leviticus</Book>
</books>

你会阅读元素,直到你想要添加一本新书,写入输出

read
    <books>

write
    <books>

read
        <Book>Genesis</Book>

write
        <Book>Genesis</Book>

然后附加您要添加​​的书

write
        <Book>Exodus</Book>

然后继续剩下的

read
        <Book>Leviticus</Book>

write
        <Book>Leviticus</Book>

read
        </books>

write
        </books>

产生 output.xml:

<books>
    <Book>Genesis</Book>
    <Bool>Exodus</Book>
    <Bool>Leviticus</Book>
</books>

使用 SAX 比将所有书籍包装在一个数组中要容易得多。除非您正在处理大量数据,否则您可能不需要这样做。


推荐阅读