I have been reducing the memory footprint of a program that uses several large arrays I have been working on by using file mapping. Since I don't know the desired size of these arrays I am overestimating the size to a level I know the arrays won't reach, and then truncating the files down to the final size I am finished with the arrays. Fortunately the code I am using to create the mapped files (at the bottom of this post), creates sparse files on every machine I have tried. If it didn't there would be a disk space problem.
Question is: is calling lseek to extend the file prior to mapping guaranteed to create a sparse file, or can it at least be relied on to do so with any reasonable Linux distro as well as Solaris.
Also is there any way of checking that the created file is sparse since it's probably better to exit than attempt to create several hundred GB of non-sparse files.
output_data_file_handle = open(output_file_name,O_RDWR | O_CREAT ,0600);
lseek(output_data_file_handle,output_file_size,SEEK_SET);
write(output_data_file_handle, "", 1);
void * ttv = mmap(0,(size_t)output_file_size,PROT_WRITE | PROT_READ, MAP_SHARED,output_data_file_handle,0);
Referring your 2nd question: To test whether the file is (partially) a sparse file you can use the stat()
command.
Example:
#include <stdio.h>
#include <sys/stat.h>
...
struct stat st = {0};
int result = stat("filename", &st);
if (-1 == result)
perror("stat()");
else
{
printf("size/bytes: %ld", st.st_size); /* 'official' size in bytes */
printf("block size/bytes: %ld", st.st_blksize);
printf("blocks: %ld", st.st_blocks); /* number of blocks actually on disk */
if (st.st_size > (st.st_blksize * st.st_blocks))
printf("file is (at least partially) a sparse file");
}
...