在文件中可靠存储java对象的最少代码
在我的小型独立Java应用程序中,我想存储信息 我的要求:在文件中可靠存储java对象的最少代码,java,xml,jaxb,file-storage,Java,Xml,Jaxb,File Storage,在我的小型独立Java应用程序中,我想存储信息 我的要求: 读写java对象(我不想使用SQL,也不需要查询) 易于使用 易于设置 最小外部依赖 因此,我希望使用jaxb将所有信息存储在文件系统中一个简单的XML文件中。我的示例应用程序如下所示(将所有代码复制到名为application.java的文件中,然后编译,无其他要求!): @XmlRootElement 类数据存储{ 字符串电子邮件地址; 列出家庭成员; //列出地址; } 公共类应用程序{ 私有静态jaxbcontextjc;
- 读写java对象(我不想使用SQL,也不需要查询)
- 易于使用
- 易于设置
- 最小外部依赖
application.java
的文件中,然后编译,无其他要求!):
@XmlRootElement
类数据存储{
字符串电子邮件地址;
列出家庭成员;
//列出地址;
}
公共类应用程序{
私有静态jaxbcontextjc;
私有静态文件storageLocation=新文件(“data.xml”);
公共静态void main(字符串[]args)引发异常{
jc=JAXBContext.newInstance(DataStorage.class);
数据存储数据存储=加载();
//主应用程序将在此处执行
//像这样的数据操作:
dataStorage.emailAddress=”me@example.com";
dataStorage.familyMembers.add(“Mike”);
保存(数据存储);
}
受保护的静态数据存储加载()引发JAXBEException{
if(storageLocation.exists()){
StreamSource source=新的StreamSource(storageLocation);
返回(数据存储)jc.createUnmarshaller().unmarshal(源);
}
返回新的数据存储();
}
受保护的静态void save(DataStorage DataStorage)引发JAXBEException{
jc.createMarshaller().marshal(数据存储、存储位置);
}
}
我如何克服这些缺点
- 多次启动应用程序可能会导致不一致
了解您的需求:
- 多次启动应用程序
- 多个用户可以在网络驱动器上运行应用程序
- 防止数据损坏
注意:在关系数据库中保存XML通常不是一个好主意。我只是建议您评估此选项,因为您似乎很自信,您只需要SQL实现所能提供的一组特定功能。考虑了一会儿后,我想尝试这样实现它:
- 打开带有最新时间戳的
-文件data..xml
- 仅使用只读模式
- 做出改变
- 将文件另存为
-不要覆盖并检查是否不存在具有较新时间戳的文件data..xml
- 通过锁定
- 通过版本控制
- 制作您自己的日志文件(即,包含要提交到实际数据文件的更改的短期独立文件)
- 在开始更改xml之前,请使用文件锁获得对该文件的独占访问权,另请参见
- 更新完成并成功关闭文件后,释放锁
- 当其中一个应用程序正在写入文件时,其他应用程序实例仍可能尝试读取该文件。这可能会导致不一致(即脏读)。确保在写入过程中,写入程序进程对文件具有独占锁定。如果无法获得独占访问锁,则写入程序必须稍等片刻,然后重试
- 读取该文件的应用程序应读取该文件(如果它可以获得访问权限,则没有其他实例执行独占锁定),然后关闭该文件。如果无法读取(由于其他应用程序锁定),请等待并重试
- 但外部应用程序(如记事本)仍可以更改xml。在读取文件时,您可能更喜欢独占读取锁定
@XmlRootElement
class DataStorage {
String emailAddress;
List<String> familyMembers;
// List<Address> addresses;
}
public class Application {
private static JAXBContext jc;
private static File storageLocation = new File("data.xml");
public static void main(String[] args) throws Exception {
jc = JAXBContext.newInstance(DataStorage.class);
DataStorage dataStorage = load();
// the main application will be executed here
// data manipulation like this:
dataStorage.emailAddress = "me@example.com";
dataStorage.familyMembers.add("Mike");
save(dataStorage);
}
protected static DataStorage load() throws JAXBException {
if (storageLocation.exists()) {
StreamSource source = new StreamSource(storageLocation);
return (DataStorage) jc.createUnmarshaller().unmarshal(source);
}
return new DataStorage();
}
protected static void save(DataStorage dataStorage) throws JAXBException {
jc.createMarshaller().marshal(dataStorage, storageLocation);
}
}