2011-09-12 7 views
4

내가해야 할 일은 전체 파일 내용을 가장 빠른 방법으로 0으로 채우는 것입니다. cp 같은 리눅스 명령을 실제로 한 번에 쓸 수있는 최상의 블록 크기 정보를 얻을 수 있지만이 블록 크기 정보를 사용하여 충분한 경우 좋은 성능을 가지고 있고 모양이 같아서 밖으로 찾을 수 없습니다. st_blksizestat()은 그 블록 크기를 제공하지 않습니다. 감사합니다. 코멘트에C에서 전체 파일을 0으로 덮어 쓰는 가장 빠른 방법은 무엇입니까?

일부 답변 :

  1. 이 필요성은 조각 같은 유틸리티를 사용하지 않는, C에서 수행한다.

  2. 는 내가 그것을 처리 할 수있는 방법을 모르는 파일 크기보다 큰 블록을 반환하는 stat()

  3. st_blksize의 사용에 오류가 없습니다.

  4. 은 여분의 공간이 0으로 채워되어 잘라 내기()/ftruncate에서()를 사용하여, 나는 전체 파일 데이터를 덮어 쓰기해야합니다.

내가 좋아하는 뭔가를 생각하고 있어요 :

fd = open("file.txt", O_WRONLY); 
// check for errors (...) 
while(TRUE) 
{ 
    ret = write(fd, buffer, sizeof(buffer)); 
    if (ret == -1) break; 
} 
close(fd); 

문제는 "프로그래밍"최적의 버퍼 크기를 정의하는 방법이다.

+4

'shred -n0 -z _filename_'을 실행하는 것은 어떻습니까? –

+1

stat st_blksize가 찾고있는 번호를 반환하지 않는다고하는 이유는 무엇입니까? 확률은 stat (2) 사용에 버그가있을 수 있으므로 코드를 게시해야합니다. –

+1

[ftruncate] (http://linux.die.net/man/2/truncate)는 어떻습니까?0으로 자른 다음 원하는 크기로 확장하십시오. –

답변

8

가장 빠르고 간단한 :

분명히
int fd = open("file", O_WRONLY); 
off_t size = lseek(fd, 0, SEEK_END); 
ftruncate(fd, 0); 
ftruncate(fd, size); 

는 일부 오류 검사를 추가하는 것이 좋을 것이다.

이 솔루션은 이 아닌 파일의 안전한 제거를 위해 사용합니다. 파일에서 사용 된 이전 블록을 사용되지 않은 것으로 표시하고 실제 공간을 차지하지 않는 스파 스 파일을 남겨두기 만합니다. ,

static const char zeros[4096]; 
int fd = open("file", O_WRONLY); 
off_t size = lseek(fd, 0, SEEK_END); 
lseek(fd, 0, SEEK_SET); 
while (size>sizeof zeros) 
    size -= write(fd, zeros, sizeof zeros); 
while (size) 
    size -= write(fd, zeros, size); 

테스트는 성능을 크게 향상시킬 수 있음을 보여줍니다 당신은 32768 정도까지 zeros의 크기를 증가시킬 수있다 : 당신이 물리적 저장 매체에서 파일의 이전 내용을 삭제하려면, 당신은 뭔가를 시도 할 수 있습니다 그러나 어떤 지점을 넘어선 도움이되어서는 안되며 단지 낭비 일뿐입니다.

+0

ftruncate (fd, 0) 다음에 ftruncate (fd, size)가 너무 많은 성능을 잃지 않습니까? – Tarantula

+0

@Tarantula : 이것은 가능한 빨리 나타납니다. – janneb

+1

그것은 거의 모든 시간을 사용하지 않아야합니다. 모든 파일 시스템 메타 데이터를 조정하기 때문에 ... –

-1

이것은 제 생각입니다. 주의 모든 오류 검사 코드를 제거하여 명확하게했습니다.

int f = open("file", "w");    // open file 
int len = lseek(f, 0, SEEK_END);  // and get its length 
lseek(f, 0, SEEK_BEG);     // then go back at the beginning 
char *buff = malloc(len);    // create a buffer large enough 
memset(buff, 0, len);     // fill it with 0s 
write(f, buff, len);     // write back to file 
close(f);        // and close 
+2

malloc에 ​​비해 파일 크기가 너무 커질 가능성이 매우 높기 때문에 엄청나게 위험한 것으로 보입니다. – KevinDTimm

+0

전적으로 동의합니다. 이것은 내가하고 싶은 것이 멀다. – Tarantula

+0

mmap –

4

mmap에와 (과 오류 검사없이) : 당신이 그것에 대해 걱정할 필요가 없습니다

stat(filename,&stat_buf); 
len=stat_buf.st_size; 
fd=open(filename,O_RDWR); 
ptr=mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); 
memset(ptr,0,len); 
munmap(ptr,len); 
close(fd); 

이, 블록 크기의 커널의 생각을 사용해야합니다. 파일이 주소 공간보다 큰 경우가 아니면

관련 문제