
私は特定のサイズのファイルが与えられた場合、すべてのバイトがディスク上で連続しているわけではないと思います。 (またはそうでしょうか?「ディスクデフラグ」というフレーズが存在するため、そうではないと思いません)。しかし、少なくともアプリケーションの観点からはそうです。つまり、head -c [-]n
+を使用してtail -c [-]n
ファイルの一部を抽出し、連続したバイトシーケンスとして処理できます。
ファイルの長さが10バイトで、すべて同じバイトを含むとします。
$ cat someFile
AAAAAAAAAA
someFile.part1
このように2つのファイルに分割できますかsomeFile.part2
?
$ cat someFile.part1
AAAAA
$ cat someFile.part2
AAAAA
実際、どのバイトもどこにも移動されませんでした。つまり、その10バイトがまだ前の位置に残っているという意味ですか?
最終的に、名前は、someFile
コンテンツが実際に起動される物理的な場所(ディスクまたはOS(またはカーネル?)が処理できる仮想メモリの種類)に何らかの形でマッピングする必要があります。ある意味では、/someFile
のようなポインタと長さに大きな違いはないと思います。一方、ターゲットファイルは/および/です。おそらく、私はC ++の経験と実際には存在しないファイルシステムの経験に影響を受けたでしょう。 :D0xabc
10
0xabc
5
0xac1
5
私はその仕事自体には興味がありません。プログラムがどのように機能するのか疑問に思います。lxsplit
職業と彼らの強みは何ですか。主に好奇心に由来するものですが、たぶん自分で書いてみるのも良いです。
答え1
通常、ファイルを分割すると、常にファイルの内容がコピーされます。私が知る限り、Linuxはファイルを分割するための他のメカニズムを提供しません。
これはほぼすべての話です。しかし、完全ではありません...
Linuxはファイルシステムドライバを使用してディスク上のファイルを管理します。ディスクに書き込まれたファイルシステムは、時々他のプログラムによって操作されることがあります。通常ファイルシステムは Linux ではマウントされません。例えばデバッグファイルext2/ext3/ext4の場合
ただし、プログラムがファイルシステム自体のバイトで動作する場合、実行できる操作には厳しい制限があります。
背景
ほとんどの(すべて?)ファイルシステムでは、ファイル名とディレクトリ名はファイルデータとは別に保存されます。ファイルの所有権やタイムスタンプなどのメタデータは、「Inode」と呼ばれる別々の場所に保存されることがよくあります。
これにより、同じファイルに2つのファイル名を追加できます(ハードリンクとも呼ばれます)。
ファイルデータはブロックに保存されます。 ext4のデフォルトのブロックサイズは4KiB(4096バイト)です。。通常、1バイトだけを保存するにはブロック全体が必要ですが、ブロックがいっぱいになるまで「無料」でより多くのバイトをファイルに保存できます。
最初のブロックがいっぱいでより多くのバイトを書き込む必要がある場合、ファイルシステムは新しい(使用可能な)ブロックを見つける必要があります。それから:
- 他のファイルがそれを使用しようとしないように、新しいブロックを使用できないとマークします。
- ファイル内のブロックの場所を記録します。
ファイルシステムごとにこれら2つの技術が異なりますが、要件は常に同じです。ファイルシステムドライバは、新しいブロックがファイルの前のブロックの直後に来るように最善を尽くしますが、これは保証されません。断片化は、次のブロックが別のファイルに割り当てられたときに発生します。
ファイルはいついくつかのブロックを静かに共有できますか?
一部のファイルシステムと一部のブロックレベルのストレージには、重複排除を実行する機能があります。あるブロックに書き込まれた正確な内容が他のブロックの正確な内容と一致する場合は、1つのブロックのみを保存できます。時々、これは重複した項目が記録されないことを意味し、時には遡及的に削除されることを意味します。
〜のようにマーカス・ミュラーは指摘した。一部のファイルシステムは重複排除を実行できます。
それもLVMの特徴これは、ファイルシステムの知識の外側のブロックレベルで発生します。
ハード制限
仮定的に、新しい inode を作成し、その inode にファイル名を追加し、1 つの inode から別の inode にブロックを再割り当てすることで、ファイルシステムを操作できます。
繰り返しますが、Linuxにはこのメカニズムはありませんが、方法がわかっている場合は、ハードドライブの実際のバイトを使用してこれを行うのに何の邪魔もありません。
バイトを移動せずにどこからでもファイルを分割することは[一般的に]不可能です。ブロックサイズは交渉できません。ほとんどのファイルシステムでは、ファイルの中央に半分しか使用されていないブロックはありません。
これは、あなたの例では、10バイトが4096の倍数または他の一般的なブロックサイズではないため、新しいブロックが(ほぼ)確実に記録されることを意味します。
ただし、ファイルシステムごとに機能が異なります。たとえば、BTRFSはテールパッキングをサポートします。
答え2
一般的にいいえ - 不可能です。ファイルシステム(非常に特別な反例を除く)は、ファイルがデータブロックとメタデータで構成されるブロック指向ストレージシステム(ディスク、SSD、NVME...)用に設計されています。メタデータには権限、ACLなどが含まれますが、特にファイルの長さと並べ替えられたファイルブロックのリストが含まれています。より進化したファイル構成がありますが、すべてデータブロックの長さと整列したリストに解析できます。
示された例では、somefileは切り捨てを介してsomefile.part1に変換できます。切り捨てには、ファイルの長さメタデータを変更し、ブロックリストから不要になったブロックを割り当て解除することが含まれます。これはすべてのコピーで実行できます。 somefile.part2を作成するのは難しいです。例では、文字5 - 10 "AAAAA"はブロックの先頭にないため(ブロックのサイズは2バイトの累乗、通常512Bまたは4096B)、次の場所にコピーされない限りファイルの最初の部分にすることはできません。ブロックの始まり。
ブロック境界でファイルデータを分割したい場合でも、カーネルファイルシステムコードはこれらの機能をユーザースペースに公開しないため、カーネルファイルシステムを変更する必要があります。