Как я могу читать / записывать фиксированное количество целых чисел из / в файл за одну операцию (настолько быстро, насколько это возможно, файл можно считать двоичным)? - PullRequest
1 голос
/ 25 марта 2020

У меня большой файл (предположим, я могу сделать его двоичным), который не помещается в ОЗУ, и я хочу отсортировать по нему числа. В процессе мне нужно быстро прочитать / записать большое количество чисел из / в файл (от / до vector<int> или int[]), поэтому я бы не хотел читать / записывать его по одному, но читать / написать его блоками с фиксированным размером. Как мне это сделать?

Ответы [ 2 ]

1 голос
/ 25 марта 2020

Вы можете использовать ostream::write для записи в файл и istream::read для чтения из файла.

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

Допустим, у вас есть vector<int>.

. Вы можете использовать следующий код для записи его содержимого в файл.

std::vector<int> myData;
// .. Fill up myData;

// Open a file to write to, in binary mode.
std::ofstream out("myData.bin", std::ofstream::binary);

// Write the size first.
auto size = myData.size();
out.write(reinterpret_cast<char const*>(&size), sizeof(size));

// Write the data.
out.write(reinterpret_cast<char const*>(myData.data()), sizeof(int)*size);

Вы можете прочитать содержимое такого файла, используя следующий код:

std::vector<int> myData;

// Open the file to read from, in binary mode.
std::ifstream in("myData.bin", std::ifstream::binary);

// Read the size first.
auto size = myData.size();
in.read(reinterpret_cast<char*>(&size), sizeof(size));

// Resize myData so it has enough space to read into.
myData.resize(size);

// Read the data.
in.read(reinterpret_cast<char*>(myData.data()), sizeof(int)*size);

Если не все данные могут поместиться в ОЗУ, вы можете прочитать и записать данные небольшими порциями. Однако, если вы читаете / пишете их небольшими порциями, я не знаю, как бы вы их отсортировали.

1 голос
/ 25 марта 2020

У меня большой файл (предположим, я могу сделать его двоичным), который не помещается в ОЗУ, и я хочу отсортировать по нему числа.

Учитывая, что файл является двоичным, возможно, самое простое и предположительно эффективное решение - это карта памяти файла. К сожалению, нет стандартного интерфейса для отображения памяти. В системах POSIX есть функция mmap.

Теперь отображаемый в память файл представляет собой просто массив необработанных байтов. Считать его массивом целых чисел технически недопустимо до тех пор, пока в C ++ 20 не будет введен C -стиль «неявное создание объектов низкого уровня». На практике это уже работает в большинстве современных реализаций языка Примечание 1 .

Чтобы эта реинтерпретация работала, представление целых чисел в файле должно соответствовать представлению целых чисел, используемому ЦП. , Файл не будет переносимым на ту же программу, работающую в других несовместимых системах.

Мы можем просто использовать std::sort для этого массива. Операционная система должна позаботиться о подкачке файла в память и из памяти. Однако алгоритм, используемый std::sort, не обязательно оптимизирован для этого варианта использования. Чтобы найти оптимальный алгоритм, вам может потребоваться провести некоторое исследование.

1 В случае, если проблема касается соответствия стандарту Pre-C ++ 20, можно выполнить итерацию по массиву, скопируйте базовые байты в целое число, поместив новый целочисленный объект в память, используя скопированное целое число в качестве нового значения. Компилятор может оптимизировать эти операции до нуля инструкций, и это делает поведение программы хорошо определенным.

...