Мне нужно прочитать массив из файла. Массив не упорядочен непрерывно в файле, приходится переходить «смещенными» байтами, чтобы получить следующий элемент.
Что более эффективно, если я прочитал очень большой файл.
1) Используйте инкрементную относительную позицию.
2) Используйте абсолютную позицию.
Опция 1:
int var[N];
seekg(0);
for (int i=0; i<N; i++) {
file.read( (char*) var+i, sizeof(int))
seekg(offset,ios_base::cur);
}
вариант 2:
int var[N];
for (int i=0; i<N; i++) {
file.seekg(offset*i);
read( (char*) var+i, sizeof(int))
}
read
будет уже продвигать позицию, поэтому вам не нужно искать внутри цикла. Более того, массивы расположены в памяти непрерывно, так что вы можете просто сказать:
std::vector<int> var(N);
auto res = file.read(reinterpret_cast<char*>(var.data()), sizeof(int) * var.size());
Просто не забудьте проверить значение res
и из file
впоследствии:
if (!file || res != sizeof(int) * var.size())
{
// an error occurred
}
Если вы читаете из случайных частей файла, то не имеет значения, как вы ищите (файлы по сути «произвольного доступа»). Но обязательно запустите вышеуказанный тест после каждого чтения ловить ошибки.
Я на 99,9% уверен, что это ничего не изменит (кроме правильности с точки зрения offset
должен быть правильно отрегулирован на то, что вы переехали sizeof(int)
байты вперед в относительном случае, а не в абсолютном. В обоих случаях вы выполняете поиск, который перемещает текущую позицию в файле. Фактический код в файловой системе, которая имеет дело с этим, в конечном итоге переместится в абсолютную позицию, вычислив ее из текущей в случае ios_base::cur
).
Если вам ДЕЙСТВИТЕЛЬНО важно знать, что лучше, сравните эти два варианта. Но я почти уверен, что в самой функции поиска в файловой системе нет абсолютно никакой разницы. Это просто большое целое число (вероятно, 64 бита), отслеживающее, в каком месте файла вы читаете (или пишете) дальше.