stat ve ls yanlış dosya boyutunu gösterir (terabayt yanlış)


5

Tamam, bir sürü vCard dosyam var, bunların hepsi 200 - 300 Byte boyutunda.

Onları arşivlemeye çalışırken, neden bu kadar uzun sürdüğünü merak ettim ve yanlış boyutta bir dosya olduğunu keşfettim. Hem ls hem de stat yaklaşık 8.1 Terabayt boyutundadır. Bu şaşırtıcı, çünkü SSD’m yaklaşık 250 Gigabayt boyutunda.

Yanlış boyutlarda başka dosyalar da var, ama bu kesinlikle en büyüğü. Zaten bir fsck verdim, ancak (ext4) dosya sisteminde hata yok gibi görünüyor. Bu yanlış boyuttan nasıl kurtulabilirim?

Sağol Wolle


2
Sadece bir tahmin, ama belki bunlar (geçersiz) seyrek dosyalar. Bu muazzam büyüklüğü açıklar.
gronostaj

onlardan nasıl kurtulurum? Ve ne kadar seyrek bir dosya sabit diskimden daha büyük olabilir?
WolleTD

1
100 sayfa alabilen bir ciltçi hayal edin. Bu cildi normal bir dosya olarak kullanırsanız, 100 sayfa ekleyebilirsiniz. 100'ü de okuyabilirsin. 100'e de yazabilirsin. Şimdi seyrek bir cildi düşün. "Sayfa 1: İçerik A" yazdığınız ilk sayfayı eklediniz. Daha sonra ikinci bir sayfayı "sayfa 9999: içerik b:" yazınız. Ne zaman bir sayfa okumaya çalışsanız, var olup olmadığına bakın. Olmazsa, cevabınız bu boş bir sayfa olacaktır . Varsa, sayfanın içeriğini döndürürsünüz. Henüz ciltleyicide olmayan bir sayfaya yazdığınızda, yeni bir sayfa eklersiniz.
Hennes

1
Peki bunu nasıl düzeltebilirim? Dosyayı bile açamıyorum ...
WolleTD

1
Dosyanın seyrek olup olmadığının kontrolü: ls -lsh fileişgal edilen boyutu yeni ilk sütuna yazdırır. Kullanılan boyut, görünen boyuttan daha küçükse, dosya seyrek olur.
pabouk

Yanıtlar:


1

vCard bir metin dosyası formatı gibi görünüyor. Bu, metin dosyalarının null içermemesi gerektiği için iyi bir şeydir - işletim sistemi yanlışlıkla dosyanın çok uzun null dizileri içeren seyrek bir dosya olduğunu düşünüyorsa, bu yardımcı olacaktır .

ls -lks bigfileİşgal edilen alanın görünen alandan farklı olup olmadığını görmek için kullanabilirsiniz .

ddVeri parçalarını (yalnızca ilk 500 bayt gibi) yeni bir dosyaya çıkarmak için kullanabilirsiniz . Daha sonra hexdumpbu öbek içinde kurtarılabilir metin olup olmadığını görmek için kullanabilirsiniz .

Dosyanın uzun boş dizilerle dolu olduğunu fark ederseniz, dosyayı okumak için bir komut dosyası kullanmayı deneyebilir ve yalnızca boş olmayan verileri yeni bir dosyaya yazabilirsiniz. Bu şekilde, her zamanki gibi geçerli bir vCard dosyası oluşturabilirsiniz.

Alternatif strings bigfileolarak, büyük dosyadan metin çıkarmak için kullanın .

Bu işlemlerin çoğu bir ig dosyasında uzun zaman alacaktır. Daha küçük bir şey üzerinde pratik yapmak isteyebilirsiniz ...


İşte bir vCard dosyası

$ cat gump.vcard
BEGIN:VCARD
VERSION:2.1
N:Gump;Forrest
FN:Forrest Gump
...
EMAIL;PREF;INTERNET:forrestgump@example.com
REV:20080424T195243Z
END:VCARD

$ file gump.vcard
gump.vcard: vCard visiting card

bozuk bir seyrek sürüm yapalım

$ dd of=sparse-file bs=1k seek=5120 count=0
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0 s, Infinity B/s

$ cat gump.vcard sparse-file > sparse-gump.vcard

$ cp --sparse=always sparse-gump.vcard really-sparse-gump.vcard

$ ls -lks *sparse*
   0 -rw-r--r-- 1 rgb rgb 5120 Jul 11 18:09 sparse-file
5136 -rw-r--r-- 1 rgb rgb 5121 Jul 11 18:10 sparse-gump.vcard
   4 -rw-r--r-- 1 rgb rgb 5121 Jul 11 18:18 really-sparse-gump.vcard

Son dosyanın diskindeki boyutun 4 blok olduğunu ancak 5121 blok veri içerdiğini unutmayın.

Bakalım orada ne var

$ hexdump really-sparse-gump.vcard | head -n 3
0000000 4542 4947 3a4e 4356 5241 0a44 4556 5352
0000010 4f49 3a4e 2e32 0a31 3a4e 7547 706d 463b
0000020 726f 6572 7473 460a 3a4e 6f46 7272 7365

$ hexdump really-sparse-gump.vcard | tail
0000230 4120 656d 6972 6163 450a 414d 4c49 503b
0000240 4552 3b46 4e49 4554 4e52 5445 663a 726f
0000250 6572 7473 7567 706d 6540 6178 706d 656c
0000260 632e 6d6f 520a 5645 323a 3030 3038 3234
0000270 5434 3931 3235 3334 0a5a 4e45 3a44 4356
0000280 5241 0a44 0000 0000 0000 0000 0000 0000
0000290 0000 0000 0000 0000 0000 0000 0000 0000
*
0500280 0000 0000
0500284

*Ofset 290 ve 0500280 arasındaki çizgiyi not edin - tüm hayali boşlukların yaşadığı yer.

$ strings really-sparse-gump.vcard > new-gump.vcard

$ ls -lks new-gump.vcard
4 -rw-r--r-- 1 rgb rgb 1 Jul 11 18:30 new-gump.vcard

$ cat new-gump.vcard
BEGIN:VCARD
VERSION:2.1
N:Gump;Forrest
FN:Forrest Gump
...
EMAIL;PREF;INTERNET:forrestgump@example.com
REV:20080424T195243Z
END:VCARD

Normal büyüklükteki vCard kartımızı büyük dosyadan kurtardık. Kilometreniz değişebilir.


0

Linux'ta (3.1'den beri) ve / veya lseek()ile, seyrek bir dosyadaki veri ve deliklerin konumlarını tanımlamak için kullanabilirsiniz . Aramayı artan bir ofset ile tekrarlayarak, veri olarak tanımlanan baytları okuyabilir ve giderken başka bir dosyaya yazabilirsiniz. Belki de bunun gibi bir şey (hata kontrolü ve diğer tedium basitlik için ihmal edilmiştir):SEEK_DATASEEK_HOLE

int fd0 = open(file, O_RDONLY, S_IRWXU);
int fd1 = open(newfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
off_t eof = lseek(fd0, 0, SEEK_END);
off_t cur = 0;
char buf[8192];
while (cur < eof) {
  off_t d = lseek(fd0, cur, SEEK_DATA);
  off_t h = lseek(fd0, d, SEEK_HOLE);
  lseek(fd0, d, SEEK_SET);
  size_t dlen = min(h - d, 8192);
  ssize_t rlen = read(fd0, buf, dlen);
  ssize_t r = write(fd1, buf, rlen);
  cur = d + rlen;
}
close(fd0);
close(fd1);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.