私の理解では、ファイルを操作するためのLinuxのsys_write syscallは、ファイルの内容を上書きする(または、最後に拡張する)だけです。
Linuxのファイルにコンテンツを挿入または削除するためのシステムコールがないのはなぜですか?
現在のすべてのファイルシステムでは、ファイルを連続メモリブロックに格納する必要がないため、効率的な実装が可能です。 (ファイルは断片化されます。)
「書き込み時のコピー」または「透過的なファイル圧縮」などのファイルシステム機能では、コンテンツを挿入する現在の方法は非常に非効率的です。
最近のLinuxシステムでは実際に可能ですが、block(ほとんどの場合4096)で、byteの粒度ではなく、一部のファイルシステム(ext4およびxfs)。
fallocate(2)
マンページからの引用:
int fallocate(int fd, int mode, off_t offset, off_t len);
[...]
ファイルスペースの縮小
mode
でFALLOC_FL_COLLAPSE_RANGE
フラグ(Linux 3.15以降で使用可能)を指定すると、ホールを残さずにファイルからバイト範囲が削除されます。縮小されるバイト範囲はoffset
から始まり、len
バイト続きます。操作が完了すると、offset+len
の位置から始まるファイルの内容がoffset
の位置に追加され、ファイルはlen
バイト小さくなります。[...]
ファイルスペースの増加
mode
にFALLOC_FL_INSERT_RANGE
フラグ(Linux 4.1以降で使用可能)を指定すると、既存のデータを上書きせずにファイルサイズ内に穴を挿入することにより、ファイルスペースが増加します。ホールはoffset
から始まり、len
バイト続きます。ファイル内に穴を挿入すると、offset
で始まるファイルの内容がlen
バイトだけ上方に(つまり、より高いファイルオフセットに)シフトされます。ファイル内に穴を挿入すると、ファイルサイズがlen
バイト増加します。
現在のすべてのファイルシステムでは、ファイルを連続メモリブロックに保存する必要がないため、
ファイルシステムでは、ファイルを連続した領域に格納する必要がない場合があります(実際には非常に柔軟性がありません)が、通常、ファイルは固定サイズのブロック(または連続したブロックのシーケンス)に格納されます。そうすることで実装が簡単になり、ブロックは通常、基礎となるデバイスのブロックサイズの倍数になります。
したがって、任意の長さのブロックの挿入を実装すると、ファイルシステムのフォーマットと実装がかなり複雑になるか、大量のデータを移動する可能性があります。それらのどちらも本当に良いものではなく、複雑なデータ構造をファイルシステムAPIの上にあるユーザースペースに構築することができます。