/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으로 지워지고 전체 파일 시스템 블록이 파일에서 제거됩니다. 호출이 성공한 후 이 범위에서 후속 읽기를 수행하면 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()
충분히 큰 덩어리입니다.