2010-03-09 2 views
62

Я уверен, что я только что пропустил это в руководстве, но как определить размер файла (в байтах) с использованием класса C++ из заголовка fstream?С помощью фильтров C++ (fstream), как вы можете определить размер файла?

+0

http://stackoverflow.com/questions/2282549/c-getting-incorrect-file-size/2289423#2289423 –

ответ

75

Вы можете открыть файл, используя ios::ate флаг (и ios::binary флаг), так tellg() функция даст вам непосредственно размер файла:

ifstream file("example.txt", ios::binary | ios::ate); 
return file.tellg(); 
+4

@ Dominik Honnef: в VS 2013 Update5 64-разрядный подход, с _ios: ate_ flag и без _seekg (0, ios: end) _ может не работать для больших файлов. Дополнительную информацию см. На странице http://stackoverflow.com/questions/32057750/how-to-get-the-filesize-for-large-files-in-c. –

+2

Это не похоже на хороший подход. [tellg не сообщает размер файла или смещение от начала в байтах] (http://stackoverflow.com/a/22986486/1835769). – displayName

+0

@displayName [cplusplus.com] (http://www.cplusplus.com/reference/istream/istream/seekg/) не согласен с этим утверждением: он действительно использует 'tellg()' для обнаружения файлов. –

49

Вы можете искать до конца, а затем вычислить разницу:

std::streampos fileSize(const char* filePath){ 

    std::streampos fsize = 0; 
    std::ifstream file(filePath, std::ios::binary); 

    fsize = file.tellg(); 
    file.seekg(0, std::ios::end); 
    fsize = file.tellg() - fsize; 
    file.close(); 

    return fsize; 
} 
+0

удивительным! thanks =) – warren

+0

изменил size_t на streampos. – AraK

+7

Из интереса, это первый звонок 'tellg' не гарантированно вернет 0? –

8

Как это:

long begin, end; 
ifstream myfile ("example.txt"); 
begin = myfile.tellg(); 
myfile.seekg (0, ios::end); 
end = myfile.tellg(); 
myfile.close(); 
cout << "size: " << (end-begin) << " bytes." << endl; 
+9

Возможно, вы захотите использовать более подходящий 'std :: streampos' вместо' long', поскольку последний может не поддерживать такой большой диапазон, как первый, а 'streampos' * - больше, чем просто целое число. –

-2

Я новичок, но это мой самоучка способ сделать это:

ifstream input_file("example.txt", ios::in | ios::binary) 

streambuf* buf_ptr = input_file.rdbuf(); //pointer to the stream buffer 

input.get(); //extract one char from the stream, to activate the buffer 
input.unget(); //put the character back to undo the get() 

size_t file_size = buf_ptr->in_avail(); 
//a value of 0 will be returned if the stream was not activated, per line 3. 
+5

, все это определяет, есть ли первый символ. Как это помогает? – warren

10

Не используйте tellg, чтобы определить точный размер файла. Длина, определяемая tellg, будет больше, чем количество символов, которые можно прочитать из файла.

Из вопроса stackoverflow tellg() function give wrong size of file?tellg не сообщает размер файла или смещение от начала в байтах. Он сообщает значение токена, которое впоследствии может быть использовано для поиска того же места и не более того. (Даже не гарантировано, что вы можете преобразовать тип в интегральный тип.). Для Windows (и большинства не-Unix-систем) в текстовом режиме нет прямого и немедленного сопоставления между данными tellg и количеством байтов, которые вы должны прочитать, чтобы добраться до этой позиции.

Если важно точно знать, сколько байтов вы можете прочитать, единственный способ надежно сделать это - прочитать. Вы должны быть в состоянии сделать это с чем-то вроде:

#include <fstream> 
#include <limits> 

ifstream file; 
file.open(name,std::ios::in|std::ios::binary); 
file.ignore(std::numeric_limits<std::streamsize>::max()); 
std::streamsize length = file.gcount(); 
file.clear(); // Since ignore will have set eof. 
file.seekg(0, std::ios_base::beg); 

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

  • Нет связанных вопросов^_^