Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect insufficient disk space when using stdio file operations in C/C++?

I am making a small program as follows:

void reserve_file_space(char* file_path, size_t amount)
{
    FILE* fp = fopen(file_path, "w+b");
    if(!fp)
    {
        printf("could not create a new file\n");
        return;
    }

    int fseek_ret = fseek(fp, amount, SEEK_SET);
    if(fseek_ret != 0)
    {
        printf("could not seek to the desired position\n");
        fclose(fp);
        return;
    }

    char garbage = 1;
    size_t ret = fwrite(&garbage, 1, 1, fp);
    if(ret != 1)
    {
        printf("could not write the garbage character\n");
    }

    fclose(fp);
}

int main(int argc, char* argv[])
{
    reserve_file_space("C:\\Users\\SysPart\\Desktop\\test.bin", 1 << 30);
    return 0;
}

The free disk space on my PC is around 500 MBs. In the main() if I invokes reserve_file_space("C:\\Users\\SysPart\\Desktop\\test.bin", 1 << 28 /*256 MB*/); it outputs a file created with exact size of 256 MB. However if I invokes reserve_file_space("C:\\Users\\SysPart\\Desktop\\test.bin", 1 << 30 /*1 GB*/); it produces the output file with size of 0 and without printing out any error notice.

How can I learn if the disk space is sufficient to handle correctly?

like image 378
duong_dajgja Avatar asked Oct 18 '22 05:10

duong_dajgja


1 Answers

How can I be learn if the disk space is sufficient to handle correctly?

The standard library has no functions for this. Seeking forward (like you did) is not guaranteed to fail, as the filesystem is at liberty to delay the actual allocation of disk space until that space is actually needed (because you are writing data to it). You only write one character, so only space for that one character (and some metainformation) is actually needed at this point.

To be really sure you will have enough space (even when considering other processes that might take up space after you checked), you would have to write random data of the desired size, then overwrite that with your actual data -- which is not an efficient way to do things.

Standard practice is to just attempt the write (without preallocation), and check that write operation for success. This also avoids a process termination leaving some "pre-reserved" but useless files lying around.

To check available disk space beforehand, you have to rely on OS specific functionality.

For POSIX systems, there is statvfs().

For WinAPI, there is GetDiskFreeSpace().

like image 150
DevSolar Avatar answered Oct 21 '22 05:10

DevSolar