
Eu fiz duas tentativas de resgate em um HDD que estava morrendo há algum tempo; Executei (GNU) ddrescue
primeiro e depois direto dd
com a busca manual. Quero obter o melhor de ambas as imagens. Como qualquer trecho vazio nos arquivos será apenas 0, AND bit a bit deve ser suficiente para mesclar os dois arquivos.
Existe um utilitário que me permite criar um arquivo que seja o OR de dois arquivos de entrada?
(Estou usando o ArchLinux, mas fico feliz em instalar a partir do código-fonte se não estiver nos repositórios)
Responder1
Não conheço nenhum utilitário que faça isso, mas deve ser bem fácil escrever um programa para fazer isso. Aqui está um exemplo esquelético em python:
#!/usr/bin/env python
f=open("/path/to/image1","rb")
g=open("/path/to/image2","rb")
h=open("/path/to/imageMerge","wb") #Output file
while True:
data1=f.read(1) #Read a byte
data2=g.read(1) #Read a byte
if (data1 and data2): #Check that neither file has ended
h.write(chr(ord(data1) | ord(data2))) #Or the bytes
elif (data1): #If image1 is longer, clean up
h.write(data1)
data1=f.read()
h.write(data1)
break
elif (data2): #If image2 is longer, clean up
h.write(data2)
data2=g.read()
h.write(data2)
break
else: #No cleanup needed if images are same length
break
f.close()
g.close()
h.close()
Ou um programa C que deveria ser executado mais rápido (mas é significativamente mais provável que tenha um bug despercebido):
#include <stdio.h>
#include <string.h>
#define BS 1024
int main() {
FILE *f1,*f2,*fout;
size_t bs1,bs2;
f1=fopen("image1","r");
f2=fopen("image2","r");
fout=fopen("imageMerge","w");
if(!(f1 && f2 && fout))
return 1;
char buffer1[BS];
char buffer2[BS];
char bufferout[BS];
while(1) {
bs1=fread(buffer1,1,BS,f1); //Read files to buffers, BS bytes at a time
bs2=fread(buffer2,1,BS,f2);
size_t x;
for(x=0;bs1 && bs2;--bs1,--bs2,++x) //If we have data in both,
bufferout[x]=buffer1[x] | buffer2[x]; //write OR of the two to output buffer
memcpy(bufferout+x,buffer1+x,bs1); //If bs1 is longer, copy the rest to the output buffer
memcpy(bufferout+x,buffer2+x,bs2); //If bs2 is longer, copy the rest to the output buffer
x+=bs1+bs2;
fwrite(bufferout,1,x,fout);
if(x!=BS)
break;
}
}
Responder2
Pitão
with open('file1', 'rb') as in1, open('file2', 'rb') as in2, open('outfile', 'wb') as out:
while True:
bytes1 = in1.read(1024)
bytes2 = in2.read(1024)
if not bytes1 or not bytes2:
break
out.write(bytes(b1 | b2 for (b1, b2) in zip(bytes1, bytes2)))
Isso é aproximadamente 10x mais rápido que a solução Python de Chris devido à leitura de 1.024 bytes por vez. Ele também usa o with open
padrão, pois é mais confiável no fechamento de arquivos (por exemplo, em caso de erro).
Isso parece funcionar para mim com Python 3.6.3 (mesclando com sucesso 2 arquivos torrent parciais), mas não foi completamente testado.
Talvez o if ...: break
padrão pudesse ser removido e, em vez disso, usarwhile in1 or in2:
Responder3
Isso não é bit a bit ou, mas funciona para (blocos inteiros de) zeros:
dd conv=sparse,notrunc if=foo of=baz
dd conv=sparse,notrunc if=bar of=baz
Devido a sparse
isso, pula a gravação de qualquer coisa que seja zero no arquivo de origem.
Então baz se parecerá com bar, mais o que quer que seja zero em bar, mas não zero em foo.
Em outras palavras, se houver dados diferentes de zero que não sejam idênticos em foo e bar, bar vence.