通过“嘈杂”的数据流发送和接收数据

3

我的Java程序将其数据保存到二进制文件中,并且(非常)偶尔由于硬件故障导致文件损坏。通常情况下,几兆字节大小的文件只有少量字节受到影响。为了应对这个问题,我可以将数据写两次,但这似乎过于浪费——我希望将文件大小增加限制在大约20%。

这对我来说似乎类似于通过“嘈杂”的数据流发送信息的问题。是否有Java库或算法可以向输出流中写入冗余信息,以便接收者可以在引入噪声时进行恢复?

5个回答

8
你需要的是纠错码。可以查看这段代码:http://freshmeat.net/projects/javafec/ 此外,维基百科文章可能会给你更多信息:http://en.wikipedia.org/wiki/Forward_error_correction 你有两种选择:前向纠错,发送冗余数据;或者错误检测系统,检查哈希值并重新请求任何已损坏的数据。如果出现损坏是预期的事情,那么采用纠错方法。不知道你的环境性质,因此无法提供更具体的建议,但这应该能让你了解如何处理这个问题。

如果您的数据分成几个部分,您可以使用分段CRC来完成此操作。根据数据大小,您可以为应该相对抗拒损坏的数据设置4-8字节之间的CRC。在每个部分的末尾写入CRC,并在检索部分时进行验证。如果CRC或数据已损坏,则该部分将无效。 - GrayWizardx

2

纠错码。如果我没记错,对于块大小而言,额外比特的数量随log n增加,因此块越大,校正位就越少。

你应该选择一种机制,在正常文本中间交错放置检验位(可能最方便的是作为额外字符)。这样可以在数据流中有可修补的空洞的同时仍然可读。


1

嘈杂通信的问题已经有了一个很好的解决方案:发送数据的哈希/CRC(与数据一起),接收方重新评估并在路上出现损坏时重新请求。

换句话说:使用哈希算法检查损坏并在必要时重新传输,而不是冗余地发送数据。


如果错误出现在存储器中,例如硬盘上,如果他只有文件的哈希值/CRC,则会丢失该信息。通过使用具有足够冗余信息的ECC,他可以在一定程度上纠正错误(取决于损失的程度)。 - Mic
我认为这不是在谈论数据传输,而是数据存储。OP正在将数据传输的验证方式与之相类比。 - GrayWizardx
啊,我误解了问题。不过,对于通信和持久化来说,哈希数据仍然是有效的。 - Paul Sasik
Mic - 这是在数据量和错误频率之间的权衡。如果错误很少且局部化,则 CRC 检查可能只需要每个块多一个字节,而纠错码则需要发送更多字节。 - Chip Uni

1
CRC和ECC是检测数据损坏(对于ECC还包括恢复)的标准答案,但是任何方案都只能应对一定程度的噪声。超出这个级别,您将得到未检测到和/或无法纠正的错误。第二个问题是,只有在注入噪声之前才能添加ECC / CRC,否则这些方案将无效。
但我有点怀疑您可能正在解决错误的问题:
  • 如果在通过通信线传输文件时发生损坏,则应使用具有内置ECC等支持的通信硬件。

  • 如果在将文件写入磁盘时发生损坏,则应更换磁盘。

  • 您还应考虑可能是您的应用程序损坏了数据;例如,由于代码中的某些同步错误。


0
听起来有些古老,但很有趣,我刚刚与一个编写“移动”应用程序(不是PDA/手机,而是钻井平台风格的现场应用)的人进行了类似的对话。由于环境的限制,他们实际上使用修改过的XMODEM CRC传输将数据写入磁盘。然而,我认为除了以下操作之外,并没有什么特别的地方:
使用RandomAccessFile在“rw”模式下写入一块数据(512-4096字节),重新读取以进行CRC检查,如果不匹配,则重新写入,否则迭代到下一块。通过操作系统文件缓存,我好奇这个方法的有效性如何?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接