#c #windows
#c #Windows
Вопрос:
Итак, в настоящее время я использую этот код для открытия указанного файла:
FILE* stream;
stream = fopen("file.txt", "w ");
Моя цель — получить размер этого файла, но я не смог найти какую-либо явную функцию, которая определяла бы размер файла в библиотеке времени выполнения CRT.
Я нашел только GetFileSize
or GetFileSizeEx
, но эти функции находятся в fileapi
заголовочном файле и используют дескрипторы вместо потоков, что означает, что мне нужно будет написать большой кусок кода только для размера файла (открытие файла, проверка достоверности, получение размера файла с помощью дескриптора, закрытие дескриптора), что приведет к дополнительным накладным расходам.
Есть идеи о том, как я мог бы сделать это с помощью процедуры CRT (например, той, которая начинается с f
префикса)?
Комментарии:
1. docs.microsoft.com/en-us/cpp/c-runtime-library/reference/…
2. Вы можете использовать
stat
с путем, если хотите. На обеих связанных страницах есть примеры. docs.microsoft.com/en-us/cpp/c-runtime-library/reference /…3. Для чего это стоит, если вы планируете открыть файл в
w
режиме, размер всегда будет равен 0, поскольку это уничтожает содержимое. en.cppreference.com/w/cpp/io/c/fopen
Ответ №1:
Типичный способ получить размер FILE*
потока — это перейти fseek()
к концу потока, а затем ftell()
к позиции, которая была фактически просмотрена.
Обратите внимание, что поток должен быть открыт в обычном "b"
режиме, чтобы отключить переводы разрывов строк, которые могут изменить позицию.
FILE* stream;
stream = fopen("file.txt", "rb");
fseek(stream, 0, SEEK_END);
long size = ftell(stream);
...
Комментарии:
1. Обратите внимание, что это не удается для файлов размером 2 ГБ и больше. Стандартная библиотека C, основанная на POSIX, в значительной степени бесполезна, когда дело доходит до ввода-вывода файлов. Реализация CRT от Microsoft обеспечивает смягчающие меры, такие как _ftelli64 и _fseeki64 .
Ответ №2:
Это то, что я придумал, однако способ @Remy Lebeau также работает.
struct _stat fd;
if(_fstat(_fileno(stream), amp;fd) != 0)
return -1;
DWORD fsize = fd.st_size;
Ответ №3:
Попробуйте это:
size_t fileSize(const char* fileName)
{
ifstream ifs;
size_t len;
ifs.open(fileName, ifstream::binary);
ifs.seekg(0, ios::end); // go to the end
len = (size_t)ifs.tellg(); // report length
ifs.close();
return len;
}
Комментарии:
1. Это можно немного упростить, используя
ifstream
конструктор для открытия и поиска потока за одну операцию и позволяя деструктору закрывать поток, когда он выходит за рамки, например:size_t fileSize(const char* fileName) { return ifstream(fileName, ifstream::binary | ifstream::ate).tellg(); }
Ответ №4:
Есть хороший способ сделать это на C 17:
#include <iostream>
#include <filesystem>
int main()
{
namespace fs = std::filesystem;
std::cout << "File size = " << fs::file_size("path_to_file");
return {};
}
Дополнительная информация здесь https://en.cppreference.com/w/cpp/filesystem/file_size