【发布时间】:2009-12-14 00:20:22
【问题描述】:
我的 Java 程序将其数据保存到一个二进制文件中,并且(非常)偶尔该文件由于硬件故障而损坏。通常只有几个字节在大小为几兆字节的文件中受到影响。为了解决这个问题,我可以将数据写入两次,但这似乎有点过头了——我宁愿将文件大小的增加限制在 20% 左右。
在我看来,这类似于通过“嘈杂”数据流发送信息的问题。是否有 Java 库或算法可以将冗余信息写入输出流,以便在引入噪声时接收器可以恢复?
【问题讨论】:
我的 Java 程序将其数据保存到一个二进制文件中,并且(非常)偶尔该文件由于硬件故障而损坏。通常只有几个字节在大小为几兆字节的文件中受到影响。为了解决这个问题,我可以将数据写入两次,但这似乎有点过头了——我宁愿将文件大小的增加限制在 20% 左右。
在我看来,这类似于通过“嘈杂”数据流发送信息的问题。是否有 Java 库或算法可以将冗余信息写入输出流,以便在引入噪声时接收器可以恢复?
【问题讨论】:
您想要的是纠错码。检查此代码:http://freshmeat.net/projects/javafec/
同样,维基百科文章可能会为您提供更多信息: http://en.wikipedia.org/wiki/Forward_error_correction
您有两种可能性:前向纠错(发送冗余数据)或错误检测系统(检查哈希值并重新请求任何已损坏的数据)。如果损坏是意料之中的事情,则可以采取纠错方法。
在不了解您的环境性质的情况下,实际上不可能提供更具体的建议,但这应该让您开始了解如何解决这个问题。
【讨论】:
纠错码。如果我没记错的话,块大小的附加位数为 log n,因此块越大,校正位数越少。
您应该选择一种在普通文本之间交错检查位(可能最方便作为额外字符)的机制。这允许在您的数据流中存在可修复的漏洞,同时仍然可以读取。
【讨论】:
嘈杂的通信问题已经有了一个很好的解决方案:发送数据的哈希/CRC(与数据一起),由接收器(重新)评估并在途中发生损坏时重新请求。
换句话说:使用哈希算法检查损坏并在必要时重新传输,而不是冗余发送数据。
【讨论】:
CRC 和 ECC 是检测和(对于 ECC)因噪声导致的数据损坏而恢复的标准答案。然而,任何方案都只能应对一定程度的噪声。超出该级别,您将获得未检测到和/或无法纠正的错误。第二个问题是,这些方案只有在您可以在注入噪声之前添加 ECC / CRC 时才有效。
但我有点怀疑你可能试图解决错误的问题:
如果在通过通讯线路传输文件时发生损坏,那么您应该使用具有内置 ECC 等支持的通讯硬件。
如果将文件写入光盘时发生损坏,则应更换光盘。
您还应该考虑可能是您的应用程序损坏了数据;例如由于您的代码中存在一些同步错误。
【讨论】:
听起来很陈旧,但很有趣,我只是与编写“移动”应用程序(不是 PDA/电话,而是石油和天然气钻机式现场应用程序)的人进行了类似的对话。由于环境的原因,他们实际上是在修改后的XMODEM CRC 传输中写入磁盘。我认为这很容易说,但是除了以下之外没有什么特别的:
在“rw”中使用 RandomAccessFile 写入数据块(512-4096 字节),重新读取以进行 CRC 检查,如果不匹配则重新写入,或迭代到下一个块。使用 OS 文件缓存,我很好奇它的效果如何?
【讨论】: