合并大文件中的非零不同字节

合并大文件中的非零不同字节

我正在尝试通过将旧的划痕 DVD 翻录为 ISO 来挽救它。我有两个阅读器,并从每个阅读器创建了一个 ISO。每个阅读器都无法读取某些不同的字节并将其替换为 0。当我使用 比较文件时cmp -l file1.iso file2.iso,我发现左侧的某些字节为 0,而某些其他右侧的字节为 0(其他文件上的相应字节为非零)。我想创建第三个文件,假设file3.iso它将上述两个文件中的非零不同字节合并。例如,为简单起见,假设每个文件有 6 个字节,如下所示

file1.iso   file2.iso
---------   ---------
0           0
1           1
2           0
3           0
0           4
0           5

file3.iso应该如下:

0
1
2
3
4
5

这些文件相当大(大约 8GB)。每个文件的字节数相同。我使用的是 Ubuntu 16.04

有人能建议最简单的方法来实现我想要的效果吗?我可以使用的输出cmp -l作为中间数据,但想避免编写代码。

答案1

我为你编写了一个 Python 脚本。

#!/usr/bin/env python3
'''
Given two input files and one output file, merge the input files on
matching bytes or bytes that are null in one file but not the other.
Non-matching non-null bytes will raise a ValueError.
'''

import sys

args = sys.argv[1:]

file1 = open(args[0], 'rb')
file2 = open(args[1], 'rb')
file_out = open(args[2], 'wb')

def get_bytes(file):
    '''Return a generator that yields each byte in the given file.'''
    def get_byte():
        return file.read(1)
    return iter(get_byte, b'')

for i, (byte1, byte2) in enumerate(zip(get_bytes(file1), get_bytes(file2))):
    if byte1 == byte2:
        byte_out = byte1
    elif ord(byte1) == 0:
        byte_out = byte2
    elif ord(byte2) == 0:
        byte_out = byte1
    else:
        msg = 'Bytes at {:#x} are both non-zero and do not match: {}, {}'
        raise ValueError(msg.format(i, byte1, byte2))
    file_out.write(byte_out)

使其可执行然后像这样调用它:

$ ./test.py file1.iso file2.iso file3.iso

或者简称:

$ ./test.py file{1,2,3}.iso

附言:我最近一直在研究以不同的方式读取文件,所以这是一个很好的意外发现。

相关内容