É possível criar uma cópia editada de um arquivo sem usar espaço extra em disco?

6

Se eu tiver um arquivo grande, posso usar ln para fazer "cópias" dele que não ocupam espaço extra em disco. Mas e se eu não quiser uma cópia exata do arquivo? Existe uma maneira de criar uma nova versão de um arquivo com algumas modificações sem precisar copiar o arquivo inteiro e usar o dobro do espaço em disco?

Minha motivação é editar tags id3 em arquivos mp3 a partir de um download de torrent. Eu não quero editar os arquivos baixados diretamente porque isso atrapalha a propagação, mas eu também não quero copiar os arquivos e usar o dobro do espaço em disco apenas para editar algumas tags id3 em seus cabeçalhos.

    
por hugomg 25.10.2014 / 13:13

3 respostas

6

Se não houver recurso embutido no programa que você usa, para sobrepor novas informações de alguma forma sobre um arquivo base, você terá que resolver isso no nível do sistema de arquivos, de forma transparente. aplicativo usando o arquivo. Devido ao seu requisito de espaço, um sistema de controle de revisão não seria suficiente, embora ele forneça várias versões.

Uma coisa que você pode investigar é armazenar os arquivos em um sistema de arquivos Btrfs e ter os originais em um instantâneo "originais" e as versões atualizadas em uma visão baseada neste instantâneo. Isso deve funcionar bem para tags ID3v1 (como são o final de um arquivo) e também para os arquivos que possuem tags ID3v2, contanto que tenham espaço reservado suficiente para as alterações e não exijam a reconfiguração do arquivo MP3. Assim, apenas os blocos reais alterados para um arquivo estão ocupando mais espaço em disco.

Se você adicionar um arquivo adicional nos originais, precisará fazer um cp --reflink src dst explícito para todos os arquivos adicionados em um estágio posterior. Seus downloads, então, funcionam com os originais e seu editor id3 (por exemplo, picard) e seu reprodutor de músicas na visualização derivada. Os arquivos inalterados (ou ainda não alterados) nessa visualização ficarão exatamente iguais aos originais.

Exemplo (começando com um volume Btrfs em /data0 e um arquivo test.mp3 em /tmp ):

/data0$ btrfs subvolume create /data0/mp3org
Create subvolume '/data0/mp3org'
/data0$ cp /tmp/test.mp3 mp3org/
/data0$ btrfs subvolume snapshot /data0/mp3org/ /data0/id3update
Create a snapshot of '/data0/mp3org/' in '/data0/id3update'

O arquivo test.mp3 agora está disponível nos dois diretórios ( mp3org e id3update ):

/data0$ ls -l /data0/mp3org
total 7600
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3
/data0$ ls -l /data0/id3update/
total 7600
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3

Altere o que está no instantâneo:

/data0$ id3v2 -c "This is a change" id3update/test.mp3
/data0$ ls -l /data0/mp3org
total 7600
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3
/data0$ ls -l /data0/id3update/
total 7608
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:24 test.mp3

O tamanho do arquivo não mudou, mas o conteúdo do segundo não mudou. Isso ocorre porque o comentário coube no espaço reservado para o id3v2 no arquivo original.

/data0$  grep -F "is a change" mp3org/* id3update/*
Binary file id3update/test.mp3 matches

Copie outro arquivo no subvolume original, ele não aparece em id3update :

/data0$ cp /tmp/test.mp3 mp3org/abc.mp3
/data0$ ls -l mp3org/ id3update/
id3update/:
total 7600
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:24 test.mp3

mp3org/:
total 15200
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:28 abc.mp3
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3

Faça uma cópia explícita do reflink:

/data0$ cp --reflink mp3org/abc.mp3 id3update/
/data0$ ls -l mp3org/ id3update/
id3update/:
total 15200
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:29 abc.mp3
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:24 test.mp3

mp3org/:
total 15200
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:28 abc.mp3
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3

E altere o novo arquivo:

/data0$ id3v2 -c "another file change" id3update/abc.mp3
/data0$ grep -F change mp3org/* id3update/*
Binary file id3update/abc.mp3 matches
Binary file id3update/test.mp3 matches

Se mp3org for preenchido automaticamente, você poderá manter id3update atualizado, executando um script regularmente, que fará o cp --reflink src dst , se o destino ainda não existir.

¹ que são mais frequentemente no início de um arquivo

    
por 25.10.2014 / 13:52
0

Usando um Sistema de Controle de Versão, como o git, você pode "fazer check-in" ou "commitar" qualquer número de versões do seu arquivo. O Git é provavelmente um dos Sistemas de Controle de Versão mais fáceis de entender, porque não requer o uso de um servidor separado; todo o trabalho pode ser feito em sua própria máquina local, e há muitas informações de tutoriais disponíveis na web. Existem também vários front-ends gráficos disponíveis para ele. O Git armazenará as diferentes versões de arquivos internamente como uma versão compactada do arquivo original e das diferenças entre as versões. Como parte do processo de confirmação, você fornece uma mensagem que descreve brevemente o estado do (s) arquivo (s) confirmado (s) e, posteriormente, você pode navegar pelas versões disponíveis e "verificar" a versão com a qual deseja trabalhar atualmente.

    
por 25.10.2014 / 15:57
0

Para encontrar a diferença, existe o comando diff - comparar arquivos linha por linha. Você pode armazenar diferenças para diff-file e a qualquer momento pode aplicá-lo por patch - aplicar um arquivo diff a um original. Mas de qualquer forma você deve primeiro fazer um segundo arquivo para fazer mudanças (você pode deletá-lo depois de receber o arquivo diff).

Se diff não puder trabalhar com arquivos binários mesmo com o parâmetro --text , você está livre para usar bsdiff ou, possível, rdiff (obrigado Anko para comentar).

    
por 25.10.2014 / 13:42