What is the fastest way to overwrite an entire file with zeros in C?

I just need to fill the entire contents of the file with zeros in the fastest way. I know that some linux commands, such as cp , actually get information about the maximum block size for writing at a time, but I could not figure out if this block size information is enough to have good performance and looks like st_blksize from stat() doesn't give me the block size. Thanks!

Some responses to comments:

  • This must be done in C without using utilities such as shred.

  • Error using stat()

  • st_blksize returns a block larger than the file size, I don’t know how I can handle this.

  • Using truncate () / ftruncate (), only the extra space is filled with zeros, I need to overwrite the whole file data.

I think in something like:

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

The problem is how to determine the optimal buffer size "programmatically".

+4
source share
3 answers

The fastest and easiest:

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

Obviously, it would be nice to add some error checking.

This solution is not , however, what you want for safe file destruction. It will simply mark the old blocks used by the file as unused and leave a sparse file that does not take up any physical space. If you want to clear the old contents of a file from physical media, you can try something like:

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

You can increase the size of zeros to 32768 or so, if testing shows that it improves performance, but for a certain point it should not help and just be a waste.

+8
source

With mmap (and without error checking):

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

This should use the idea of ​​a kernel block size, so you do not need to worry about it. If the file is larger than your address space.

+4
source

This is my idea; mind you, I deleted every error checking code for clarity.

 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 
-1
source

All Articles