Czy plik, który był pierwotnie rzadki, a następnie rozwinięty, może zostać ponownie zmieniony?

29

Wiem, że kopiowanie lub przesyłanie tego, co pierwotnie było rzadkie, bez użycia narzędzia, które rozumie rzadkie pliki, spowoduje wypełnienie „dziur”. Czy istnieje metoda lub narzędzie, które pozwala zamienić to, co kiedyś było rzadkim plikiem, na rzadkie?

Na przykład:
utwórz rzadki plik:

% dd if=/dev/zero of=TEST bs=1 count=0 seek=1G
# do some op that pads out the holes
% scp TEST localhost:~/TEST2
% ls -lhs TEST*
   0 -rw-rw-r--. 1 tony tony 1.0G Oct 16 13:35 TEST
1.1G -rw-rw-r--. 1 tony tony 1.0G Oct 16 13:37 TEST2

Czy jest jakiś sposób na:

% resparse TEST2
to get:
   0 -rw-rw-r--. 1 tony tony 1.0G Oct 16 13:35 TEST
  0G -rw-rw-r--. 1 tony tony 1.0G Oct 16 13:37 TEST2
użytkownik25849
źródło
Przepraszam, musiałem poprawić oryginalne pytania ...
user25849,
1
Jedyną rzeczą, która może to zrobić z tego, co widziałem, jest GNU „cp”, jak w „% cp --sparse = zawsze poprzednio-rzadki plik nowo-rzadki-plik„ Ktoś to nie zrobi ” w miejscu'.
user25849,
Jeśli chcesz skopiować rzadki plik i pozwolić, aby kopia była rzadka, użyj rsync -aS.
Gilles „SO- przestań być zły”

Odpowiedzi:

30

Edytuj 2015

od wersji ut-linux 2.25 fallocatenarzędzie w Linuksie ma do tego opcję -d/ --dig-hole.

fallocate -d the-file

Wykopałby dziurę dla każdego bloku pełnego zer w pliku


W starszych systemach możesz to zrobić ręcznie:

Linux ma taką FALLOC_FL_PUNCH_HOLEopcję fallocate. Znalazłem skrypt na githubie z przykładem:

Używanie FALLOC_FL_PUNCH_HOLE z Python

Zmodyfikowałem go trochę, aby zrobić to, o co prosiłeś - dziurawić dziury w obszarach plików wypełnionych zerami. Oto on:

Używanie FALLOC_FL_PUNCH_HOLE z Pythona do wybijania dziur w plikach

usage: punch.py [-h] [-v VERBOSE] FILE [FILE ...]

Punch out the empty areas in a file, making it sparse

positional arguments:
  FILE                  file(s) to modify in-place

optional arguments:
  -h, --help            show this help message and exit
  -v VERBOSE, --verbose VERBOSE
                        be verbose

Przykład:

# create a file with some data, a hole, and some more data
$ dd if=/dev/urandom of=test1 bs=4096 count=1 seek=0
$ dd if=/dev/urandom of=test1 bs=4096 count=1 seek=2

# see that it has holes
$ du --block-size=1 --apparent-size test1
12288   test1
$ du --block-size=1 test1
8192    test1

# copy it, ignoring the hole
$ cat test1 > test2
$ du --block-size=1 --apparent-size test2
12288   test2
$ du --block-size=1 test2
12288    test2

# punch holes again
$ ./punch.py test2
$ du --block-size=1 --apparent-size test2
12288   test2
$ du --block-size=1 test2
8192    test2

# verify
$ cmp test1 test2 && echo "files are the same"
files are the same

Zauważ, że punch.pywyszukuje tylko bloki 4096 bajtów do wybicia, więc może nie tworzyć pliku tak rzadkiego, jak w momencie uruchamiania. Oczywiście może być mądrzejszy. Ponadto jest tylko lekko przetestowany , więc bądź ostrożny i wykonaj kopie zapasowe, zanim mu zaufasz!

Jim Paris
źródło
1
Najbardziej podoba mi się to, ponieważ nie wymaga ponownego przepisywania całego pliku.
Peter
8

Jeśli chcesz zmniejszyć rozmiar pliku, możesz to zrobić bezpośrednio za pomocą dd.

dd if=./zeropadded.iso of=./isnowsparse.iso conv=sparse

Z dd(1)instrukcji:

          sparse   If one or more output blocks would consist solely of
                   NUL bytes, try to seek the output file by the required
                   space instead of filling them with NULs, resulting in a
                   sparse file.

Zauważ, że będzie szukał tylko wtedy, gdy cały blok będzie pusty. Dla maksymalnego wykorzystania rzadkości bs=1.

bahamat
źródło
2
Każdy rozmiar bloku mniejszy niż bs=512naprawdę nie ma sensu, ponieważ dyski są urządzeniami blokowymi. ( bs=4096w nowszych dyskach)
lapo
wygląda na to, że jest to odpowiednikcp --sparse=always zeropadded.iso isnowsparse.iso
maxschlepzig
2

Krótko mówiąc - tarpodbicie go -Sflagą (przy założeniu tar GNU) i ponowne wykonanie scp... nie. Żadne narzędzie, o którym wiem, nie wiedziałoby, gdzie są „dziury”.

zadzwonić
źródło
5
GNU cp wykona ponowną analizę pliku: Ze strony podręcznika
user25849,
Niesamowite. Naucz się czegoś każdego dnia - kiedy wprowadzono tę flagę? Raz na jakiś czas opłaca się czytać strony
podręcznika
2

Miałem z tym szczęście:

cd whatever
rsync -avxWSHAXI . .

Te -Isiły rsync, aby zaktualizować wszystkie pliki, niezależnie od tego, czy myśli, że się zmieniłem, czy też nie; -Spowoduje, że nowe pliki do sparsified. -asprawia, że ​​dzieje się to rekurencyjnie, dzięki czemu można sparsyfikować całe drzewa katalogów za pomocą jednego polecenia.

To nie jest tak dobre, jak narzędzie na zamówienie, które wyszukuje dziury i niszczy je FALLOC_FL_PUNCH_HOLE, ale lepiej niż duplikować całe drzewa katalogów.

David Given
źródło