我有一个程序,我正在为一个小企业,这是在linkedList上实现序列化来保存数据。这一切都很好,直到我有两个工作人员试图向列表中添加更多数据,其中一个最终覆盖了另一个。
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();
}
}
我怎样才能在同一时间从两台不同的计算机上保存数据到我的文件中,而不会有一台计算机覆盖另一台计算机?
这是一个如何获取/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();
显然,如果您需要高并发性,那么读取一个顺序文件,仔细考虑一段时间,然后重写或不重写是禁止的。这就是为什么这些应用程序通常使用数据库系统,即客户机-服务器范式。文件系统上的混战是不可容忍的,除非在极少数情况下。您的组织可以一次将数据更新分配给一个人,这将简化问题。
向列表中添加更多数据,其中一个最终会覆盖另一个。
这就是文件的默认工作方式,实际上ObjectOutputStream不支持"追加"模式。一旦你关闭了流,你就不能改变它了。
我怎样才能在同一时间从两台不同的计算机上保存数据到我的文件中,而不会有一台计算机覆盖另一台计算机?
你有两个问题
- 如何在不丢失信息的情况下两次写入文件。
- 如何协调进程之间的写操作而不影响其他进程。
对于第一部分,您需要首先读取列表的内容,添加您想要添加的条目,并再次写出内容。或者您可以将文件格式更改为支持追加的格式。
对于第二部分,您需要使用某种锁。一种简单的方法是创建一个锁文件。您可以自动创建第二个文件,例如file.lock
,并且成功创建文件的进程持有锁,该进程修改文件并删除已完成的锁。一定要小心,确保你总是把锁拆下来。
另一种方法是使用文件锁。你必须注意不要在进程中删除文件,但是这样做的好处是,如果你的进程死亡,操作系统会清理锁。