Если у меня есть огромный файл (например, 1 ТБ или любой размер, который не помещается в ОЗУ. Файл хранится на диске). Он ограничен пространством. А моя оперативная память - всего 8 ГБ. Могу ли я прочитать этот файл в ifstream? Если нет, то как читать блок файла (например, 4 ГБ)?Как читать огромный файл в C++
ответ
Есть несколько вещей, которые вы можете сделать.
Во-первых, нет проблем с открытием файла, который больше, чем объем оперативной памяти, который у вас есть. То, что вы не сможете сделать, это скопировать весь файл вживую в вашу память. Лучше всего было бы найти способ читать всего несколько кусков за раз и обрабатывать их. Вы можете использовать ifstream
для этой цели (например, ifstream.read
). Выделяю, скажем, один мегабайт памяти, прочитать первый мегабайт этого файла в него, промыть и повторить:
ifstream bigFile("mybigfile.dat");
constexpr size_t bufferSize = 1024 * 1024 * 1024;
unique_ptr<char[]> buffer(new char[bufferSize]);
while (bigFile)
{
bigFile.read(buffer.get(), 1024 * 1024 * 1024);
// process data in buffer
}
Другим решением является отображение файла в память. Большинство операционных систем позволяют вам отображать файл в память, даже если он больше физического объема памяти, который у вас есть. Это работает, потому что операционная система знает, что каждая страница памяти, связанная с файлом, может быть отображена и отключена по требованию: когда вашей программе нужна определенная страница, ОС будет считывать ее из файла в память вашего процесса и заменять страницу, не используется некоторое время.
Однако это может работать, только если файл меньше максимального объема памяти, который теоретически может использовать ваш процесс. Это не проблема с 1TB-файлом в 64-битном процессе, но он не будет работать в 32-разрядном процессе.
Также be aware of the spirits that you're summoning. Отображение памяти - это не то же самое, что чтение с него. Если файл неожиданно усечен из другой программы, ваша программа, скорее всего, выйдет из строя. Если вы измените данные, возможно, у вас закончится нехватка памяти, если вы не сможете сохранить обратно на диск. Кроме того, алгоритм вашей операционной системы для подкачки в памяти и из памяти может не вести себя так, чтобы вы значительно выигрывали. Из-за этих неопределенностей я бы рассмотрел отображение файла только в том случае, если его чтение в кусках с использованием первого решения не может работать.
В Linux/OS X вы использовали бы для этого mmap
. В Windows вы должны открыть файл, а затем использовать CreateFileMapping
, затем MapViewOfFile
.
Сторона примечания: обычная ошибка; не тестируя операцию потока: 'while (bigFile) {bigFile.read (...); ...} ' –
Вы можете использовать fread
char buffer[size];
fread(buffer, size, sizeof(char), fp);
Или, если вы хотите использовать C++ fstreams вы можете использовать read, как buratino сказал.
Также имейте в виду, что вы можете открыть файл независимо от его размера, идея состоит в том, чтобы открыть его и прочитать его в патронах, которые вписываются в вашу оперативную память.
Он спросил о 'ifstream'. Я считаю, что более релевантный вызов функции будет [читать] (http://www.cplusplus.com/reference/istream/istream/read/) – buratino
Я прочитал fread doc. Поэтому, если я использую 'FILE * pFile; pFile = fopen ("myfile.txt", "rb"); 'и myfile.txt не могут быть помещены в ОЗУ, могу ли я открыть его таким образом? – ZigZagZebra
fopen не загружает файл в ram, поэтому да, вы должны быть в состоянии сделать это без проблем. – marian0
Более авансы Подход является вместо чтения всего файла или его куски в памяти вы можете отобразить его в память, используя специфичные для платформы API:
Под окнами: CreateFileMapping(), MapViewOfFile()
Под linux: open (2)/creat (2), shm_open, mmap
вам нужно будет скомпилировать 64-битное приложение, чтобы оно работало.
для получения более подробной информации смотрите здесь: CreateFileMapping, MapViewOfFile, how to avoid holding up the system memory
Уверен, что вам не нужно хранить весь файл в памяти. Обычно нужно читать и обрабатывать файл кусками. Если вы хотите использовать ifstream
, вы можете сделать что-то вроде этого:
ifstream is("/path/to/file");
char buf[4096];
do {
is.read(buf, sizeof(buf));
process_chunk(buf, is.gcount());
} while(is);
- 1. Как читать огромный файл CSV в Mule
- 2. Как читать огромный HTML-файл в Java?
- 3. Прочитайте огромный текстовый файл в C++
- 4. Прочитайте огромный файл матрицы в C
- 5. Как читать огромный файл csv в R по условию строки?
- 6. Python: как читать огромный текстовый файл в памяти
- 7. Как читать огромный файл на Java, в кусках без блокировки?
- 8. Как читать огромный текстовый файл через javascript или jquery?
- 9. Как обрезать огромный текстовый файл?
- 10. Как разбить огромный текстовый файл в python
- 11. Огромный файл main.cs
- 12. Загрузите огромный файл в память
- 13. как разобрать огромный файл с определенным текстом
- 14. проанализируйте огромный файл csv с помощью C++
- 15. Как grep огромный XML-файл?
- 16. как создать огромный json-файл
- 17. как разобрать огромный XML-файл
- 18. Как читать файл на C++?
- 19. Python - мелочь в огромный файл
- 20. Сортировать огромный файл
- 21. Как читать огромный файл и записывать файл в java с использованием горизонтального или вертикального масштабирования
- 22. Alamofire upload огромный файл
- 23. Как читать файл в вектор в C++?
- 24. symfony огромный файл скачать
- 25. Показать огромный файл в GUI
- 26. читать csv файл в C++
- 27. Стабильный сортировать огромный файл
- 28. xml_parse огромный файл PHP
- 29. C/C++ огромный заголовок/источник
- 30. Как читать файл .c с помощью C++
Как это ограничено? Это текстовый текст? Вы можете читать строки за раз? – nicomp
@nicomp Я сомневаюсь, что у вас может быть текстовый файл размером 1 ТБ. –
Невозможно. Вы не можете поместить 1 ТБ в любую ОЗУ меньше, чем это. Если вы хотите извлечь данные из этого файла, это может быть возможно. –