如何故意對文件進行碎片化

如何故意對文件進行碎片化

我正在尋找一種對現有文件進行分段的方法,以便評估某些工具的效能。我找到了一個名為 NTFS 檔案系統的解決方案我的碎片器如本文所述。但是我找不到 ext2/3/4 的任何內容...我想我可以開發自己的文件碎片器,但由於時間限制,我想找到更快的解決方案。我找到了一些工具,例如HJ-分裂它將文件分割成更小的部分,但我懷疑這會模擬文件碎片。

他們可以解決我的問題嗎?

答案1

如果你想確保碎片但不防止它(所以你只能部分控制發生的事情),並且你不關心碎片的細節,這是一種快速而骯髒的做事方式。

若要建立n至少包含兩個片段的區塊檔案:

  1. 使用同步寫入開啟文件,寫入 m < n 區塊。
  2. 開啟另一個文件。加到它,直到磁碟上最多有 n - m 區塊可用。不要錯誤地將其稀疏!
  3. 將剩餘的 n - m 區塊寫入第一個檔案。
  4. 關閉unlink第二個文件。

您可以透過交錯更多文件來分割更多片段。

這假設檔案系統可用於此類折磨,即不在多使用者或關鍵任務環境中。它還假設檔案系統沒有保留區塊,或者保留區塊是為您的 UID 保留的,或者您是 root。

沒有直接的確保碎片的方式,因為 Unix 系統採用檔案系統抽象,所以你永遠不會與原始檔案系統交談。

此外,請確保檔案系統層級碎片不會告訴您較低層級發生的情況。 LVM、軟體和硬體 RAID、硬體級磁區重新映射和其他抽象層可能會對您的期望(和測量)造成嚴重破壞。

答案2

我還沒有遇到 Linux 上的通用檔案系統會犧牲寫入吞吐量而不是連續檔案。也就是說,如果檔案以非順序順序寫入,則每個檔案系統都會產生碎片,尤其是對於稀疏檔案。

簡單的方法:透過 torrent 用戶端運行檔案-最好是不預先分配檔案的用戶端。 BitTornado 或 rtorrent 符合這個要求。 (前者有可配置的分配模式)

困難的方法:將原始檔分割成幾KB大小的片段,然後將它們打亂。開啟目標檔案。對於每一篇文章,找到它的正確位置並寫下來。

這是一個執行此操作的 Perl 腳本:

#!/usr/bin/perl

use List::Util qw/shuffle/;
use IO::Handle;

use constant BLOCK_SIZE => 4096;

my ($src, $dst) = @ARGV;

my $size = (stat($src))[7];
my @blocks = shuffle(0 .. ($size / BLOCK_SIZE));

my ($srcfh, $dstfh);
open $srcfh, "<", $src or die "cannot open $src: $!";
open $dstfh, ">", $dst or die "cannot open $dst: $!";
truncate $dstfh, $size; # undefined behaviour

my $buf;
for my $blockno (@blocks) {
  seek $_, $blockno * BLOCK_SIZE, 0 for ($srcfh, $dstfh);
  read $srcfh, $buf, BLOCK_SIZE;
  print $dstfh $buf;
  $dstfh->flush;
}

close $dstfh;
close $srcfh;

filefrag您可以使用 e2fsprogs 套件中包含的命令檢查碎片。

以下是 torrent 的作用範例:

# ls -sh amd64memstick-5.1.2.fs.gz
239M amd64memstick-5.1.2.fs.gz
# filefrag amd64memstick-5.1.2.fs.gz
amd64memstick-5.1.2.fs.gz: 585 extents found

這是我的腳本(在 ext3 上)得到的結果:

$ ls -sh source.tar
42M source.tar
$ perl fragment.pl source.tar fragmented.tar
$ md5sum fragmented.tar source.tar
f77fdd7ab526ede434f416f9787fa9b3  fragmented.tar
f77fdd7ab526ede434f416f9787fa9b3  source.tar
# filefrag fragmented.tar
fragmented.tar: 395 extents found

編輯:沒關係,除了較大的檔案(肯定是 1.5 GB 的檔案碎片)之外,它似乎根本無法正常工作。

VM 系統可能正在快取並推遲/重新排序太小的寫入。這就是為什麼 torrent 用戶端會設法產生碎片(因為它們通常不會以 >10MB/s 的速度下載),但我的腳本卻不會。我認為可以透過降低虛擬機器閾值來調整。看/proc/sys/vm/dirty_*

答案3

我偶然發現一個情況,需要在Linux ext4中產生碎片檔案。我是透過打電話這樣做的錯誤定位,可用於在給定文件上打孔,這會將孔回收到可用磁碟空間,從而導致碎片。看這裡用於產生碎片檔案(以及附加的故事)的腳本。透過這種方式,可以輕鬆創建數千個片段(或範圍)。

相關內容