【问题标题】:How to write serializable objects in XML files without overwrite the file? SAXParseException如何在 XML 文件中写入可序列化对象而不覆盖文件? SAXParseException
【发布时间】:2018-09-13 21:52:39
【问题描述】:

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

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

This is what it shows to me. It continues running but never write to the file.

【问题讨论】:

  • 当您尝试读取文件时是否收到 SAXParseException?可能是您的 library.xml 文件为空或格式错误。理想情况下,您应该将文件读取和写入逻辑从输入循环中分离出来。您尚未展示如何打开 output 进行写作,将其包括在内会很有帮助。
  • 嘿@Geoff 谢谢你的答案。我很感激所以我编辑了帖子并包含了整个代码。在我将对象发送到填充后,我立即得到 SAXParseException,然后它向我显示了消息。应用程序继续运行,但它从不写入文件。

标签: java xml parsing


【解决方案1】:

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

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

流式处理示例: 例如,如果您的输入是 输入.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 更容易使用,而不是将所有书籍包装在一个数组中。 除非您处理大量数据,否则您可能不需要这样做。

【讨论】:

  • 那么,这里我什至不需要 ArrayList?它只是写入临时文件然后将其放入原始文件中?以及如何在文件中间插入一些元素?
  • @user9954844 可以将原文件中直到插入点的所有内容写入临时文件,然后将要插入的数据写入临时文件,然后将原文件中的所有内容写入临时文件的插入点。或者您可以将所有内容读入数组列表,关闭原始文件并将列表中的数据写回它。你不需要两者。
  • 我无法理解“直到临时文件的插入点”。如何将其指定给我的程序?对不起,我是新手。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2020-03-28
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
相关资源
最近更新 更多