在C中用零覆盖整个文件的最快方法是什么?

时间:2011-09-12 18:19:36

标签: c linux file unix file-io

我需要做的是以最快的方式用零填充整个文件内容。我知道像cp这样的一些linux命令实际上得到了一次写入的最佳块大小信息,但我无法弄清楚使用这个块大小信息是否足以具有良好的性能和外观就像来自st_blksize的{​​{1}}并没有给我那个块大小。 谢谢!

评论的一些答案:

  1. 这需要在C中完成,而不是使用像shred这样的实用程序。

  2. 使用stat()

  3. 时没有错误
  4. stat()返回的文件大小超过文件大小, 我不知道怎么办呢。

  5. 使用truncate()/ ftruncate(),只填充额外的空格 零,我需要覆盖整个文件数据。

  6. 我想的是:

    st_blksize

    问题是如何“以编程方式”定义最佳缓冲区大小。

3 个答案:

答案 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);

如果测试表明它可以提高性能,那么你可以将zeros的大小增加到32768左右,但超过某一点它不应该有所帮助,只会浪费。

答案 1 :(得分: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);

这应该使用内核对块大小的想法,因此您不必担心它。除非文件大于您的地址空间。

答案 2 :(得分:-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