2016-07-27 1 views
4

Я делаю небольшую программу следующим образом:Как определить недостаточное дисковое пространство при использовании файлов stdio в C/C++?

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

Свободное дисковое пространство на моем компьютере составляет около 500 МБ. В main(), если я вызываю reserve_file_space("C:\\Users\\SysPart\\Desktop\\test.bin", 1 << 28 /*256 MB*/);, он выдает файл, созданный с точным размером 256 МБ. Однако, если я вызываю reserve_file_space("C:\\Users\\SysPart\\Desktop\\test.bin", 1 << 30 /*1 GB*/);, он выдает выходной файл размером 0 и не выдает никаких сообщений об ошибке.

Как узнать, достаточно ли свободного места на диске?

+3

Первое, что нужно сделать, это проверить возвращаемое значение 'fseek' и даже' fclose'. – kaylum

+0

@kaylum я сделал. Все они возвратили 0 в двух вызовах. –

+0

@kaylum Проверка возвращаемого значения fclose имеет смысл. Спасибо! –

ответ

2

Как я могу узнать, достаточно ли свободного места на диске?

Стандартная библиотека не имеет никаких функций для этого. Поиск вперед (как и вы) не гарантируется сбой, так как файловая система позволяет задерживать фактическое распределение дискового пространства до тех пор, пока это пространство не понадобится (потому что вы пишете ему данные). Вы пишете только один символ, поэтому в этот момент на самом деле требуется только пространство для этого символа (и некоторой метаинформации).

Чтобы быть уверенным, что у вас будет достаточно места (даже если вы рассмотрите другие процессы, которые могут занимать место после проверки), вам придется записывать случайные данные требуемого размера, а затем перезаписывать их фактическими данными - что не является эффективным способом делать что-то.

Стандартная практика заключается в том, чтобы просто попытаться написать (без предварительного использования) и проверить, чтобы операция записи была успешной. Это также позволяет избежать завершения процесса, оставив некоторые «предварительно зарезервированные», но бесполезные файлы.

Чтобы проверить доступное дисковое пространство заблаговременно, вы должны опираться на функциональные возможности ОС.

Для систем POSIX существует statvfs().

Для WinAPI есть GetDiskFreeSpace().

+1

Но, как всегда, проверяя, достаточно ли места, тогда ваша операция создает условие гонки, когда другая программа, возможно, уже использовала свободное пространство, прежде чем вы доберетесь до него. См. [Этот пост] (https://blogs.msdn.microsoft.com/oldnewthing/20160714-00/?p=93875) для решения для Windows о том, как предварительно выделить пространство без необходимости записи в файл. – RedX

+0

@RedX: Я упомянул о состоянии гонки, и я также упомянул, почему предварительное распределение, возможно, не лучший путь вперед. – DevSolar

+0

Извините, я пропустил очень важное предложение в скобках. Ссылка, которую я предоставляю, - это сообщение, в котором подробно описано, как зарезервировать место под окнами без необходимости записи в файл. Я попытался прояснить это в своем первом комментарии. – RedX

Смежные вопросы