Java 选择正确的文件格式

Java 选择正确的文件格式,java,file,serialization,format,file-format,Java,File,Serialization,Format,File Format,我正在开发一个应用程序,应该可以保存/加载数据。大多数数据存储在类的实例中。实例中的数据包括: 一个double[][]数组 一些字符串、int、bool和一些枚举数 我有多个这样的实例+一些全局数据,我想存储在一个文件中 到目前为止,我使用 DataOutputStream out = new DataOutputStream(FileOutputStream(file)); out.writeInt()/writeBoolean()/writeUTF()/etc 这很好,问题是它不是很

我正在开发一个应用程序,应该可以保存/加载数据。大多数数据存储在类的实例中。实例中的数据包括:

  • 一个
    double[][]
    数组
  • 一些
    字符串、int、bool
    和一些枚举数
我有多个这样的实例+一些全局数据,我想存储在一个文件中

到目前为止,我使用

DataOutputStream out = new DataOutputStream(FileOutputStream(file));
out.writeInt()/writeBoolean()/writeUTF()/etc

这很好,问题是它不是很灵活。如果我在容器类中添加/删除一些变量,就没有简单的方法使旧格式保持兼容。我开始使用在文件开头添加的版本号。但这会导致每个格式版本都有一个大的loadData/closeData方法

基于文本的文件是不可能的,因为它们为我的双数组占用了太多的空间

你知道解决这个问题的好方法吗?也就是说,定义一种向后兼容的格式,它不会产生大量代码?如有任何建议,我们将不胜感激

我想到的一个想法是用一个整数标记每个变量,标识该变量。因此,格式应该是
[identifier1][variable1(字符串)][identifier2][variable2(双[]])]…

我也想过序列化,但我没有任何经验,也不知道这样做是否正确

如果您需要有关数据的更多信息或一些示例,请发表评论。

谷歌良好的跨平台(和跨语言)存储数据的方式,已经具备向后兼容性,可以尝试一下吗

文件的这一部分特别适用于您的案例:

可以很容易地引入新字段,不需要检查数据的中间服务器可以简单地解析数据并传递数据,而不需要了解所有字段


本地数据库怎么样,比如or?非常轻量级,并且省去了标记变量的麻烦,允许灵活选择检索数据。

不要走序列化路径。。。 它充满了石头和不相容性。一旦更改了一个数据对象,一切都会被破坏。谷歌protobuf是一个非常好的解决方案。在c中使用过一次++


了解如何配置文件格式需要付出一些努力,但肯定是值得的。

我在使用
序列化时从来没有遇到过任何问题,在使用序列化时应该注意的事情很少

////--------------序列化何时失败------------////

-删除实例变量时

-当实例变量的数据类型更改时

-非静态实例变量变为静态实例变量时

-非瞬态实例变量变为瞬态变量时

-当类在层次结构中上移或下移时

-当一个序列化的类变为非序列化时。

////------------当序列化未生效时-----------------////

-添加实例变量时

-当实例变量的访问说明符更改时

-瞬态实例变量转换为非瞬态实例变量时


-当您添加或删除类时。

“我开始使用我在文件开头添加的版本号”,你是说serialVersionUID?@GuilhermetoresCastro不,我还没有使用序列化,只是一些整数,每次更改文件格式时都会增加。@brimborium它不起作用,这就是为什么我删除了我最初的评论。我认为对你来说,将类中的每个变量分别序列化,并用变量名称索引这些块可能更容易。这可能意味着要编写一个巨大的开关(variableName){…},但是,因为你必须将每个变量转换成适当的类型,虽然这可以通过反射部分自动化mechanism@Qnan至少他只需要一种方法……如果数据只被应用程序的同一个实例使用,这可能是我的一个选择,但我不是SQL的超级粉丝。我认为这会带来很多开销(代码方面的,而不是数据方面的),而不仅仅是我自己一个人去做……似乎没有那么多不同类型的数据需要保存,你可以编写一些helper方法来访问数据库(varargs对于stmt.setObject()来说是一个巨大的痛苦解脱),谢谢你的建议,听起来这是一个合理的可能性。尽管我对协议缓冲区编译器的步骤有点怀疑。但是,嘿,谷歌使用它,所以它不会那么糟糕它实际上是一个非常好的库,我从未使用它的唯一原因是.NET提供了在其框架库中已经烘焙过的类似功能(满足我的需要)。虽然我读过很多关于它的文章,但我可以肯定地说,如果我必须再用C++编程,我会使用它。我对PosiBuffi感到满意(虽然我不喜欢额外的编译步骤)。谢谢你的建议。好的,对protobuf的第二个建议。我肯定在调查此事请记住,protobuf要求您将.proto文件编译为.java,这可能会使您的开发周期陷入困境,因为它需要安装protoc程序。话虽如此,这是一个快速、灵活的解决方案。@Matt这正是我不喜欢的。但我几乎可以肯定的是,有一个eclipse插件,它可以自动完成这些工作