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

Tar*_*ula 4 c unix linux file-io file

我需要做的是以最快的方式用零填充整个文件内容.我知道一些linux命令cp实际上得到了一次写入的最佳块大小信息,但是我无法弄清楚使用这个块大小信息是否足以具有良好的性能并且看起来像st_blksize来自stat()isn给我块大小.谢谢 !

评论的一些答案:

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

  2. 使用中没有错误 stat()

  3. st_blksize 返回一个大于文件大小的块,不知道我该如何处理.

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

我想的是:

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

问题是如何"以编程方式"定义最佳缓冲区大小.

R..*_*R.. 8

最快最简单:

int fd = open("file", O_WRONLY);
off_t size = lseek(fd, 0, SEEK_END);
ftruncate(fd, 0);
ftruncate(fd, size);
Run Code Online (Sandbox Code Playgroud)

显然,添加一些错误检查会很好.

虽然这个解决方案不是你想要的安全删除文件.它只是标志着由文件为未使用用过的旧块,并留下一个稀疏文件不占用任何物理空间.如果要从物理存储介质中清除文件的旧内容,可以尝试以下操作:

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);
Run Code Online (Sandbox Code Playgroud)

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

  • @R:第二种方法不能保证适用于"安全删除".特别是,它不适用于COW文件系统,如BTRFS或ZFS. (2认同)