Какой самый быстрый способ перезаписать весь файл нулями в C? - PullRequest
4 голосов
/ 12 сентября 2011

Что мне нужно сделать, это заполнить все содержимое файла нулями как можно быстрее.Я знаю, что некоторые команды Linux, такие как cp, на самом деле получают лучшую информацию о размере блока для записи за один раз, но я не смог понять, достаточно ли использовать эту информацию о размере блока, чтобы иметь хорошую производительность и выглядеть какst_blksize из stat() не дает мне такой размер блока.Спасибо!

Некоторые ответы на комментарии:

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

Проблема в том, как определить лучший размер буфера "программно".

Ответы [ 3 ]

8 голосов
/ 12 сентября 2011

Самый быстрый и простой:

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 или около того, если тестирование показывает, что оно повышает производительность, но после определенного момента это не должно помочь и будет просто пустой тратой.

4 голосов
/ 12 сентября 2011

С 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);

Это должно использовать представление ядра о размере блока, поэтому вам не нужно беспокоиться об этом.Если файл не превышает ваше адресное пространство.

0 голосов
/ 12 сентября 2011

Это моя идея; обратите внимание, я удалил все ошибки проверки кода для ясности.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...