序列化覆盖数据

时间:2014-08-04 06:17:22

标签: java serialization linked-list

我有一个程序,我正在为一个小型企业制作,它在LinkedList上实现serializable以保存数据。这一切都运行正常,直到我有两名工作人员尝试将更多数据添加到列表中,一个最终覆盖另一个。

JButton btnSaveClientFile = new JButton("Save Client File");
    btnSaveClientFile.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent arg0) {
            // add new items to list
            jobList.add(data);
            .
            .
            .

            Controller.saveData();
        }
    });
    btnSaveClientFile.setBounds(10, 229, 148, 23);
    frame.getContentPane().add(btnSaveClientFile);

这种方法导致一个人覆盖另一个,所以我尝试这样做

    JButton btnSaveClientFile = new JButton("Save Client File");
    btnSaveClientFile.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent arg0) {

            Controller.retrieveData();
            // add new items to list
            jobList.add(data);
            .
            .
            .

            Controller.saveData();
        }
    });
    btnSaveClientFile.setBounds(10, 229, 148, 23);
    frame.getContentPane().add(btnSaveClientFile);

当我使用这个时,我根本没有添加任何数据到列表中。这是我的序列化方法。这个用于保存我的数据。

    // methods to serialize data
public static void saveData() {
    System.out.println("Saving...");
    FileOutputStream fos = null;
    ObjectOutputStream oos = null;

    try {
        fos = new FileOutputStream("Data.bin");
        oos = new ObjectOutputStream(fos);

        oos.writeObject(myOLL);

        oos.close();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    }

这个用于收集我的数据

    public static void retrieveData() {
    // Get data from disk
    System.out.println("Loading...");
    FileInputStream fis = null;
    ObjectInputStream ois = null;

    try {
        fis = new FileInputStream("Data.bin");
        ois = new ObjectInputStream(fis);

        myOLL = (OrderedLinkedList) ois.readObject();
        ois.close();
    } catch (Exception ex) {
        System.err.println("File cannot be found");
        ex.printStackTrace();
    }
    }

如何制作,以便我可以在同一时间从两台不同的计算机将数据保存到我的文件中,而不会覆盖另一台计算机?

2 个答案:

答案 0 :(得分:1)

这是一个演示(并不意味着以这种原始方式使用)如何获取文件/ tmp / data上的锁。

RandomAccessFile raf = new RandomAccessFile( "/tmp/data", "rw" );
FileChannel chan = raf.getChannel();
FileLock lock = null;
while( (lock = chan.tryLock() ) == null ){
    System.out.println( "waiting for file" );
    Thread.sleep( 1000 );
}
System.out.println( "using file" );
Thread.sleep( 3000 );
System.out.println( "done" );
lock.release();

显然,如果您需要高级别的并发性,那么读取一个顺序文件,仔细考虑它然后重写或不重写是令人望而却步的。这就是为什么这些应用程序通常使用数据库系统,即客户端 - 服务器范例。除非在极少数情况下,否则文件系统上的free-for all是不可容忍的。您的组织可能能够一次向一个人分配数据更新,这将简化问题。

答案 1 :(得分:0)

  

向列表中添加更多数据,最终覆盖另一个。

这是文件默认工作的方式,实际上ObjectOutputStream不支持"追加"模式。关闭流后,您无法对其进行更改。

  

如何制作,以便我可以在同一时间从两台不同的计算机将数据保存到我的文件中,而不会覆盖另一台计算机?

这里有两个问题

  1. 如何在不丢失信息的情况下两次写入文件。
  2. 如何协调进程之间的写入,而不会影响另一方。
  3. 对于第一部分,您需要首先阅读列表的内容,添加要添加的条目,然后再次写出内容。或者您可以将文件格式更改为支持附加的格式。

    对于第二部分,您需要使用某种锁定。一种简单的方法是创建一个锁文件。您可以原子地创建第二个文件,例如file.lock和成功创建文件的那个持有锁,该进程改变文件并删除完成的锁。需要注意确保始终取消锁定。

    另一种方法是使用文件锁。您必须注意不要删除该过程中的文件,但这样做的好处是,如果您的进程终止,操作系统将清除锁定。