/dev/random
バイナリデータストリーム(例:など)があるとします/dev/zero
。- 最大Nサイズのファイルがあります。
- Nの単位はギガバイトです。
お持ちですか?エレガントなものは何でもこれを達成するためのLinuxの方法/技術/ハッキング文書連続書き込みの長さは最大Nバイトで、常に最後に書き込んだデータのみ(順番に)含まれますか?これは大きな移動(ファイルからファイルへ、メモリからファイルへ)がなく、最後/最初のデータブロックへの小さな調整のみを意味します。
私が探している秘訣は、ファイルが前方に移動し始めて、古すぎる(ファイルサイズがN以上に増加する)、つまりコンテンツの回転を効果的に忘れてしまうことです。
期待の原理は次のように表現することができる。
inp = fopen(stream, "r");
out = fopen(file, "wN"); // "Special open" with maximal size of N
while (is_reading)
{
if (rd = fread(buff, block_size, 1, inp))
{
fwrite(buff, rd, 1, out); // Old content forgotten
fflush(out); // Allow others to instantly see the current content
}
}
fclose(inp);
fclose(out);
答え1
Linuxでは、次のものを使用できます。fallocate()
ファイルの先頭からデータの割り当てを取り消します。
ファイルスペースの割り当て解除
モードでFALLOC_FL_PUNCH_HOLEフラグ(Linux 2.6.38以降で使用可能)を指定すると、オフセットから始まりlenバイトまで続くバイト範囲でスペースが確保されます(たとえば、穴の作成)。指定された範囲内で、一部のファイルシステムブロックがゼロにクリアされ、ファイルシステムブロック全体がファイルから削除されます。呼び出しが成功した後にこの範囲で後続の読み取りを実行すると、0が返されます。
...
これにより、報告されたファイルサイズなどは変更されませんが、次ls
のstat
理由で物理ディスクの使用量が減少します。ファイルがまれになります。。ファイルの「穴」から読み取ろうとする試みはまだ成功し、0
読み込みプロセスに埋められたバイトを返します。
このような:
size_t maxSize = 512UL * 1024UL * 1024UL;
char buffer[ 8 * 1024 ];
struct stat sb;
int in = open( inputFile, O_RDONLY );
int out = open( outputFile, O_WRONLY | O_CREAT | O_APPEND, 0644 );
fstat( out, &sb );
size_t fileSize = sb.st_size;
for ( ;; )
{
ssize_t bytesRead = read( in, buffer, sizeof( buffer ) );
if ( bytesRead < 0 )
{
break;
}
ssize_t bytesWritten = write( out, buffer, bytesRead );
if ( bytesWritten < 0 )
{
break;
}
fileSize += bytesWritten;
if ( fileSize > maxSize )
{
fsync( out );
off_t endOfHole = fileSize - maxSize;
fallocate( out, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
0UL, endOfHole );
}
}
XFS、BTRFS、EXT4、および tmpfs でのみサポートされます。
さらに、より多くのエラーチェックが必要であり、そのままコンパイルされない可能性があります。また、最大サイズに達すると、fallocate()
毎回read()
/write()
サイクルを呼び出し、毎回ファイルの先頭から「穴」を開けるので、非常に非効率的です。
このIOモードにバッファリングされた/を使用することもfread()
意味がありません。fwrite()
ただread()
/write()
十分に大きな塊です。