Bisakah file yang awalnya jarang dan kemudian diperluas dibuat jarang?

29

Saya tahu bahwa menyalin atau mentransfer apa yang awalnya merupakan file jarang tanpa menggunakan utilitas yang mengerti file jarang akan menyebabkan 'lubang' diisi. Apakah ada metode atau utilitas untuk mengubah file yang tadinya jarang menjadi kembali?

Sebagai Contoh:
buat file jarang:

% 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

Apakah ada cara untuk:

% 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
pengguna25849
sumber
Maaf, saya harus cukup
menjawab
1
Satu-satunya hal yang dapat melakukan ini dari semua yang saya lihat adalah GNU 'cp', seperti pada '% cp --sparse = selalu-dulu-file-jarang-baru-file-jarang-' File-detractor itu tidak akan melakukannya ' di tempat'.
user25849
Jika Anda ingin menyalin file jarang dan membiarkan salinannya jarang, gunakan rsync -aS.
Gilles 'SANGAT berhenti menjadi jahat'

Jawaban:

30

Edit 2015

pada util-linux 2.25, fallocateutilitas di Linux memiliki -d/ --dig-holeopsi untuk itu.

fallocate -d the-file

Akan menggali lubang untuk setiap blok yang penuh dengan nol dalam file


Pada sistem yang lebih lama, Anda dapat melakukannya dengan tangan:

Linux memiliki FALLOC_FL_PUNCH_HOLEopsi untuk fallocatedapat melakukan ini. Saya menemukan skrip di github dengan contoh:

Menggunakan FALLOC_FL_PUNCH_HOLE dari Python

Saya memodifikasinya sedikit untuk melakukan apa yang Anda minta - membuat lubang di wilayah file yang diisi dengan nol. Ini dia:

Menggunakan FALLOC_FL_PUNCH_HOLE dari Python untuk membuat lubang pada file

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

Contoh:

# 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

Perhatikan bahwa punch.pyhanya menemukan blok 4096 byte yang dapat dilempar keluar, sehingga mungkin tidak membuat file persis seperti ketika Anda mulai. Itu bisa dibuat lebih pintar, tentu saja. Juga, ini hanya diuji ringan , jadi hati-hati dan buat cadangan sebelum mempercayainya!

Jim Paris
sumber
1
Saya suka ini yang terbaik karena tidak perlu menulis ulang seluruh file lagi.
Peter
8

Jika Anda ingin membuat file jarang, Anda dapat melakukannya langsung dengan dd.

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

Dari dd(1)manual:

          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.

Jadi, perhatikan bahwa ia akan mencari ke depan hanya jika seluruh blok kosong. Untuk penggunaan sparseness maksimum bs=1.

bahamat
sumber
2
Ukuran blok apa pun yang kurang dari bs=512tidak terlalu masuk akal, karena disk adalah perangkat blok. ( bs=4096dalam drive yang lebih baru)
lapo
Sepertinya ini setara dengancp --sparse=always zeropadded.iso isnowsparse.iso
maxschlepzig
2

Pendek- tarup dengan -Sbendera (dengan asumsi GNU tar), dan menjalankan kembali scp... no. Tidak ada utilitas yang saya tahu akan memiliki cara untuk mengetahui di mana "lubang" berada.

Tink
sumber
5
GNU cp akan membuat ulang file: Dari halaman manual: Tentukan --sparse = selalu membuat file DEST yang jarang setiap kali file SOURCE berisi urutan yang cukup panjang dari nol byte.
user25849
Luar biasa. Belajar sesuatu setiap hari - kapan bendera itu diperkenalkan? Membayar untuk membaca halaman manual dari program "terkenal" sesekali; D
tink
2

Saya beruntung dengan ini:

cd whatever
rsync -avxWSHAXI . .

The -Ipasukan rsync untuk memperbarui semua file, terlepas dari apakah itu mengira mereka telah berubah atau tidak; yang -Smenyebabkan file baru akan disebarkan. -amembuatnya terjadi secara rekursif sehingga Anda dapat menyebarkan seluruh pohon direktori dalam satu perintah.

Ini tidak sebagus alat yang dipesan lebih dahulu yang mencari lubang dan menghancurkannya FALLOC_FL_PUNCH_HOLE, tetapi lebih baik daripada harus menduplikasi seluruh pohon direktori.

David Given
sumber