0

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

先决条件:

  1. 应该是跨平台的
  2. 要持久化的信息包括单个 POJO 和任意字节 [](实际上是文件,POJO 将其名称存储在字符串 [] 中)
  3. 只需要顺序访问
  4. 应该是一种检查数据一致性的方法
  5. 应该小而快
  6. 应该防止使用存档器+记事本的普通用户修改数据

目前我正在使用 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. 您建议阅读有关该主题的哪些内容?

TIA。

4

8 回答 8

3

它看起来很疯狂。

  • 为什么要发明一种新的文件格式?
  • 为什么要试图阻止只有愚蠢的用户更改文件?
  • 为什么使用二进制格式(难以压缩)?
  • 为什么使用接收时无法解析的格式?(接收方必须接收整个文件才能对文件采取行动。)
  • XML 已经是一种可压缩的序列化格式。所以你正在序列化一个序列化的格式。
于 2009-02-21T08:20:52.373 回答
2

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

于 2009-02-19T22:30:58.833 回答
2

1)这看起来很正常吗?

它看起来相当理智。但是,如果您要发明自己的格式而不是仅仅使用Java 序列化,那么您应该有充分的理由。你有什么好的理由(在某些情况下确实存在)?使用 XStream 的标准原因之一是使结果易于阅读,而二进制格式会立即丢失。您是否有充分的理由使用二进制格式而不是人类可读的格式?请参阅这个问题,了解为什么人类可读性好(和坏)。

把所有东西都放在一个签名的罐子里不是更容易吗?已经有标准的 Java 库工具可以执行此操作,并且您可以获得压缩和验证。

2)您将使用什么作为分隔符以及如何确定它?

我会在块之前显式存储每个块的长度,而不是分隔符。它同样简单,并且可以防止您在分隔符自行出现时将其转义。

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

这里有示例代码,看起来很合理。

4)关于这个主题,你建议阅读什么?

关于序列化的主题?我读过有关 Java 序列化、JSON和 XStream 序列化的信息,因此我了解了它们的优缺点,尤其是人类可读文件的好处。我还会查看一个经典的文件格式,例如来自 Microsoft,以了解在每个字节都很重要的时代可能的设计决策,以及这些是如何扩展的。例如:WAV 文件格式

于 2009-02-20T08:03:50.673 回答
2

让我们看看这应该很简单。

先决条件:

0.应该是跨平台的

1. 要持久化的信息包括单个 POJO 和任意 byte[]s(实际上是文件,POJO 将其名称存储在 String[] 中)

2. 只需要顺序访问

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

4.应该小而快

5.应该防止普通用户使用存档器+记事本修改数据

好吧,你猜怎么着,你已经拥有它了,它已经内置在平台中了:对象序列化

如果您需要减少在线中发送的数据量并提供自定义序列化(例如,您可以为给定对象仅发送 1,2,3 而不使用属性名称或类似的东西,并以相同的顺序读取它们, ) 你可以以某种方式使用这个“隐藏功能”

如果你真的需要它在“纯文本”中,你也可以对其进行编码,它需要几乎相同数量的字节。

例如这个bean:

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

可以这样表示:

rO0ABXNyAApTaW1wbGVCZWFuPB4W2ZRCqRICAAFMAAd3ZWJzaXRldAASTGphdmEvbGFuZy9TdHJpbmc7eHB0ABhodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20=

看到这个答案

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

于 2009-02-21T10:05:59.827 回答
1

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

不过可能没那么有趣。

于 2009-02-19T22:36:12.143 回答
1

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

  • 二进制 XML(快速信息集,Bnux)
  • 黑森州
  • 谷歌数据包缓冲区

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

所以也许还要考虑:

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

于 2009-02-24T20:33:15.333 回答
0

Bencode可能是要走的路。

这是 Daniel Spiewak 的出色实现

不幸的是,bencode 规范不支持 utf8,这对我来说是个大问题。

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

于 2009-02-20T09:00:11.617 回答
0

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

这种类型的大多数标准文件格式只使用 CRC,因为它的计算速度更快。如果要防止故意修改,MD5 更合适。

于 2009-02-20T21:02:39.100 回答