Dif / patch binário para arquivos grandes no linux?


13

Eu tenho duas imagens de partição (A e B) e quero usá-las para criar um patch que eu possa aplicar em A em outro computador para obter a nova imagem B sem inundar a rede. Eu tenho os seguintes requisitos:

  • trabalha no Linux
  • pode criar diffs
  • pode usar diffs para corrigir arquivos
  • pode lidar com arquivos binários
  • pode lidar com arquivos grandes (algumas centenas de GB devem funcionar)
  • nenhuma interação do usuário é necessária (apenas um aplicativo de console)
  • idealmente, deve ser capaz de ler / gravar em pipes (para que eu possa canalizar a partir de um arquivo compactado com gzip e gravar em um)

Existe algo assim?


Apertei a tecla Enter muito rápido ao iniciar a recompensa. Aqui está o texto que eu gostaria de adicionar:
Basj 03/02

Uma resposta com um exemplo fácil de reproduzir rdiffseria valiosa para referência futura. Exemplo: digamos file1e file2sejam dois arquivos semelhantes de 1 GB cada. 1) Como calcular o rdiff? 2) Como salvar este rdiff em um patcharquivo? 3) Como aplicar este patcharquivo file1para recuperar file2?
Basj 03/02

Respostas:


13

Você provavelmente deve dar uma olhada nas ferramentas relacionadas ao rsync: rdiff e rdiff-backup . O rdiffcomando permite produzir um arquivo de correção e aplicá-lo a algum outro arquivo.

O rdiff-backupcomando usa essa abordagem para lidar com diretórios inteiros, mas acho que você está trabalhando com imagens de disco de arquivo único, então rdiffserá a única a usar.


11
O que significa "assinatura" e "delta" para rdiff? A página de manual não diz.
Tor Klingberg 12/09

11
Para responder minha própria pergunta, criar um delta com rdiff é um processo de duas etapas. Primeiro, crie um arquivo de assinatura a partir do arquivo antigo, depois use a assinatura e o novo arquivo para criar o delta. Eles podem ser executados em conjunto comrdiff signature oldfile | rdiff delta - newfile deltafile
Tor Klingberg 13/16

11
@TorKlingberg Você poderia postar uma nova resposta com um exemplo? Digamos file1e file2são dois arquivos semelhantes de 1 GB cada. 1) Como calcular o diff? 2) Como salvar este diff em um arquivo de patch? 3) Como aplicar esse arquivo de patch file1para recuperar file2?
Basj 03/02

7

O xdelta pode fazer tudo o que você quiser. No entanto, se as suas imagens não forem muito semelhantes, você poderá acabar com um patch muito grande, porque o xdelta usa metade do buffer de memória definido para encontrar diferenças. Mais informações estão disponíveis na página da wiki TuningMemoryBudget . Aumentar o tamanho do buffer pode ajudar bastante.

O bsdiff é outra opção, mas tem muita memória RAM e é totalmente inapropriado para qualquer coisa do tamanho de uma imagem de disco.

O bsdiff tem muita memória. Requer max(17*n,9*n+m)+O(1)bytes de memória, onde né o tamanho do arquivo antigo e mo tamanho do novo arquivo. bspatch requer n+m+O(1)bytes.


3

Resposta canônica

Com relação à rdiff da publicação, o librsync 2.0.1 é uma boa leitura para o esclarecimento da funcionalidade do comando, por isso mencionei isso abaixo para preservar o conteúdo dessa resposta, se nada mais.

É importante tentar entender bem as três etapas do rdiff para atualizar um arquivo: assinatura , delta e patch, conforme mencionado na página do manual do rdiff . Eu também encontrei um rdiffscript de exemplo de comando no GitHub que é útil, que eu vou referenciar e citar.

Essencialmente...

  1. Com um arquivo "inicial" ou base [ file1] e você cria um arquivo de assinatura a partir dele
    • Geralmente é muito menor que o próprio arquivo base / original
  2. Com o arquivo de assinatura, você o compara com outro arquivo [ file2] semelhante ao seu arquivo base, mas diferente ( por exemplo, atualizado recentemente ) e cria um arquivo delta contendo apenas as diferenças entre os dois arquivos
  3. Use o " delta apenas diferenças" ou o arquivo delta e compare-o com o seu arquivo base [ file1] para gerar um novo arquivo contendo as alterações do outro arquivo [ file2] correspondente aos dois.

Comandos rápidos (por rdiff-example.sh)

rdiff signature file1 signature-file            ## signature base file1
rdiff delta signature-file file2 delta-file     ## delta differences file2
rdiff patch file1 delta-file gen-file           ## compare delta to file1 to create matching file2

rdiff-example.sh

# $ rdiff --help
# Usage: rdiff [OPTIONS] signature [BASIS [SIGNATURE]]
#              [OPTIONS] delta SIGNATURE [NEWFILE [DELTA]]
#              [OPTIONS] patch BASIS [DELTA [NEWFILE]]

# Options:
#   -v, --verbose             Trace internal processing
#   -V, --version             Show program version
#   -?, --help                Show this help message
#   -s, --statistics          Show performance statistics
# Delta-encoding options:
#   -b, --block-size=BYTES    Signature block size
#   -S, --sum-size=BYTES      Set signature strength
#       --paranoia            Verify all rolling checksums
# IO options:
#   -I, --input-size=BYTES    Input buffer size
#   -O, --output-size=BYTES   Output buffer size

# create signature for old file
rdiff signature old-file signature-file
# create delta using signature file and new file
rdiff delta signature-file new-file delta-file
# generate new file using old file and delta
rdiff patch old-file delta-file gen-file
# test
diff -s gen-file new-file
# Files gen-file and new-file are identical

Introdução

O rdiff é um programa para calcular e aplicar deltas de rede. Um delta rdiff é um delta entre arquivos binários, descrevendo como um arquivo básico (ou antigo) pode ser editado automaticamente para produzir um arquivo de resultado (ou novo).

Diferentemente da maioria dos programas diff, o librsync não requer acesso aos dois arquivos quando o diff é calculado. A computação de um delta requer apenas uma pequena "assinatura" do arquivo antigo e o conteúdo completo do novo arquivo. A assinatura contém somas de verificação para blocos do arquivo antigo. Usando essas somas de verificação, o rdiff encontra os blocos correspondentes no novo arquivo e calcula o delta.

Os deltas do rdiff geralmente são menos compactos e também mais lentos para produzir do que xdeltas ou diferenças de texto regulares. Se for possível ter os arquivos antigos e novos presentes ao calcular o delta, o xdelta geralmente produzirá um arquivo muito menor. Se os arquivos que estão sendo comparados são texto sem formatação, o diff do GNU geralmente é uma escolha melhor, pois os diffs podem ser vistos por humanos e aplicados como correspondências inexatas.

O rdiff se destaca quando não é conveniente ter os dois arquivos presentes ao mesmo tempo. Um exemplo disso é que os dois arquivos estão em máquinas separadas e você deseja transferir apenas as diferenças. Outro exemplo é quando um dos arquivos foi movido para arquivo ou mídia de backup, deixando apenas sua assinatura.

Simbolicamente

signature(basis-file) -> sig-file

delta(sig-file, new-file) -> delta-file

patch(basis-file, delta-file) -> recreated-file

Use padrões

Uma aplicação típica do algoritmo rsync é transferir um arquivo A2 de uma máquina A para uma máquina B que possui um arquivo semelhante A1. Isso pode ser feito da seguinte forma:

  1. B gera a assinatura rdiff de A1. Chame isso de S1. B envia a assinatura para A. (A assinatura geralmente é muito menor que o arquivo que descreve.)
  2. A calcula o delta rdiff entre S1 e A2. Chame esse delta D. A envia o delta para B.
  3. B aplica o delta para recriar A2. Nos casos em que A1 e A2 contenham execuções de bytes idênticos, o rdiff deve proporcionar uma economia significativa de espaço.

fonte


11
Muito obrigado!
Basj 07/02

1

JDIFF é um programa que gera as diferenças entre dois arquivos (binários).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.