为java开发(文件)交换格式

时间:2009-02-19 22:26:29

标签: java serialization binary format

我想提出一种二进制格式,用于以POF(普通旧文件;)的形式在应用程序实例之间传递数据。

先决条件:

  1. 应该是跨平台的
  2. 要保留的信息包括单个POJO&任意byte [] s(文件实际上,POJO将它的名字存储在String [])
  3. 仅需要顺序访问
  4. 应该是一种检查数据一致性的方法
  5. 应小而快
  6. 应该阻止普通用户使用archiver + notepad修改数据
  7. 目前我正在使用DeflaterOutputStream + OutputStreamWriter和InflaterInputStream + InputStreamReader来保存/恢复使用XStream序列化的对象,每个文件一个对象。读者/作者使用UTF8。 现在,需要扩展它以支持前面描述的。 我对格式的看法:

    {serialized to XML object}
    {delimiter}
    {String file name}{delimiter}{byte[] file data}
    {delimiter}
    {another String file name}{delimiter}{another byte[] file data}
    ...
    {delimiter}
    {delimiter}
    {MD5 hash for the entire file}
    
    1. 这看起来是否合理?
    2. 您将使用什么作为分隔符,您将如何确定它?
    3. 在这种情况下计算MD5的正确方法是什么?
    4. 你有什么建议阅读这个主题?
    5. TIA。

8 个答案:

答案 0 :(得分:3)

它看起来像是INsane。

  • 为什么要发明一种新的文件格式?
  • 为什么要阻止只有愚蠢的用户更改文件?
  • 为什么要使用二进制格式(难以压缩)?
  • 为什么要使用在接收时无法解析的格式? (接收方必须先接收整个文件才能对文件进行操作。)
  • XML已经是一种可压缩的序列化格式。所以你要序列化一个序列化的格式。

答案 1 :(得分:2)

模型的序列化(如果你进入MVC)不是另一种方式吗?我更喜欢使用语言(或标准库)中的东西,而不是在可能的情况下使用自己的东西。我能看到的唯一问题是文件大小可能比你想要的大。

答案 2 :(得分:2)

1)这看起来是否合理?

看起来相当理智。但是,如果您要创建自己的格式而不是仅使用Java serialization,那么您应该有充分的理由。你有什么好的理由(在某些情况下确实存在)吗?使用XStream的标准原因之一是使结果成为人类可读的,二进制格式立即丢失。您是否有充分的理由使用二进制格式而不是人类可读的格式?请参阅this question了解人类可读性好(和坏)的原因。

将所有内容放入已签名的jar中会不会更容易。已经有standard Java librariestools来执行此操作,您可以获得压缩和验证。

2)你会对分隔符使用什么以及如何确定它?

而不是分隔符,我会在块之前明确地存储每个块的长度。它同样容易,并且如果它自己出现,就可以防止你不得不逃脱分隔符。

3)在这种情况下计算MD5的正确方法是什么?

example code here看起来很合理。

4)你有什么建议阅读这个主题?

关于序列化的主题?我读过有关Java序列化,JSON和XStream序列化的内容,因此我理解了每个序列化的优缺点,尤其是人类可读文件的优点。我还会看一下像Microsoft这样的经典文件格式,以便在每个字节重要的日子里了解可能的设计决策,以及如何扩展它们。例如:The WAV file format

答案 3 :(得分:2)

让我们看看这应该非常简单。

  

先决条件:

     

0。应该是跨平台的

     

1。要保留的信息包括单个POJO&任意byte [] s(文件实际上,POJO将它的名称存储在String []中)

     

2。只需要顺序访问

     

3。应该是一种检查数据一致性的方法

     

4。应该小而快

     

5。应该阻止普通用户使用archiver + notepad修改数据

好吧猜猜看,你已经拥有它了,它已经内置在平台上了: Object Serialization

如果您需要减少线路中发送的数据量并提供自定义序列化(例如,您可以仅为给定对象发送1,2,3而不使用属性名称或类似内容,并在相同的序列,)你可以用某种方式"Hidden feature"

如果你真的需要它在“text plain”中你也可以编码它,它需要几乎相同的字节数。

例如这个bean:

import java.io.*;
public class SimpleBean implements Serializable  { 
    private String website = "http://stackoverflow.com";
    public String toString() { 
        return website;
    }
}

可以这样表示:

rO0ABXNyAApTaW1wbGVCZWFuPB4W2ZRCqRICAAFMAAd3ZWJzaXRldAASTGphdmEvbGFuZy9TdHJpbmc7eHB0ABhodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20=

See this answer

此外,如果您需要一个合理的协议,您还可以查看Google的内部交换格式Protobuf

答案 4 :(得分:1)

您可以使用zip(rar / 7z / tar.gz / ...)库。许多存在,大多数都经过了很好的测试,它可能会节省你一些时间。

虽然可能不那么有趣。

答案 5 :(得分:1)

我同意,这听起来并不像你需要一种新格式或二元格式。 如果你真的想要二进制格式,为什么不首先考虑其中一种:

  • 二进制XML(快速信息集,Bnux)
  • Hessian矩阵
  • google数据包缓冲区

但除此之外,许多文本格式也应该可以正常工作(或者更好);更容易调试,广泛的工具支持,压缩到与二进制相同的大小(二进制压缩效果差,信息理论表明,对于相同的有效信息,实现了相同的压缩率 - 这在我的测试中也是如此)。

所以也许还要考虑:

  • Json运作良好;通过base64进行二进制支持(例如,http://jackson.codehaus.org/
  • XML也不错;高效的流解析器,其中一些具有base64支持(http://woodstox.codehaus.org/,“org.codehaus.stax2.typed.TypedXMLStreamReader”下的“类型化访问API”。)

所以听起来你只想建立自己的东西。作为一种爱好没有任何问题,但如果是这样,你需要考虑它。 可能不是您正在构建的系统的要求。

答案 6 :(得分:0)

Bencode可能是最佳选择。

这是Daniel Spiewak的excellent implementation

不幸的是,bencode规范不支持utf8,这对我来说是一个不错的选择。

可能会在稍后讨论,但目前xml似乎是一个更好的选择(将blob序列化为Map)。

答案 7 :(得分:0)

也许您可以解释这比使用现有的文件格式(如JAR)更好。

此类型的大多数标准文件格式仅使用CRC作为其计算速度更快。如果您想要防止故意修改,MD5更合适。