LINUX.ORG.RU
ФорумTalks

[опять C++] Класс с заковыркой


0

0

Нужен класс, который бы представлял файл в виде массива. Каждый элемент этого массива — это 1 слово из файла.

Заковырка заключается в том, что файл нельзя подгружать в память целиком. Т.е. чтобы при tmp=myclassarr[N] переменная tmp становилось бы равна N-ному слову из файла таким путём (как я себе это представляю):

file.seekg(0);
for(int i=0; i<N; ++i) file >> tmp;

Может кто-нибудь сделать?
Кстати, ту программу я с горем пополам сделал: http://nopaste.com/p/ac1Tcopzk

Хотелось бы чтобы было так:

MyClass("data.txt") myclassarr; //-> открывает файл data.txt на чтение с помощью ifstream
tmp=myclassarr[3];//-> tmp становится равным третьему слову файла
tmp=myclassarr.flenght;//-> tmp становится равным кол-ву слов в файле

★★★★★
Ответ на: комментарий от madcore

Как нечем? Я баги на багзиллу КДЕ постю.

Obey-Kun ★★★★★
() автор топика

То, что тебе нужно называется memory mapped file.  К ним есть много различных интерфейсов.  Win32 и POSIX предоставляют API для mapped files.  Если тебя интересует сугубо C++, то смотри в сторону boost::iostreams::mapped_file: http://www.boost.org/doc/libs/1_38_0/libs/iostreams/doc/index.html

Использовать как-то так:

#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/stream_buffer.hpp>
#include <boost/iostreams/mapped_file.hpp>

namespace io = boost::iostreams;

typedef io::stream<io::mapped_file_source>         my_stream;
typedef io::stream_buffer<io::mapped_file_source>  my_streambuf;

int main() {
    my_streambuf buf("big_input_file.bin");  // неформатированный ввод через stream_buf интерфейс
    my_stream    my_in(&buf);

    std::istream & in = my_in;  // форматированный ввод через istream интерфейс
}

alexeiz
()

я извиняюсь, но задача не полна. или ограничиваем потребляемую вообще память или ограничиваем время доступа\отклика на вызов.

при неважном времени отклика: каждый раз открываем файл, пересчитываем слова в нём, возвращаем нужное.

при неважно сколько объёме памяти, но не подгрузке целиком:

при первом обращении делаем что-то вроде пар

номер слова --- положение в файле (индекс).

номера слов можно взять подряд идущими или каждое 10-ое к примеру.

короче, сложная задача какая-то

gunja
()
Ответ на: комментарий от alexeiz

> То, что тебе нужно называется memory mapped file.

Не факт: под 32-битной ОС шибко большой файл не мапнется. А вот тупо делать seek+read на каждый operator[] - вполне нормальное решение. Будет тормозить - надо будеть дальше думать, как разгонять: можно mmap кусками делать или кешировать или ещё что-нибудь изобрести.

const86 ★★★★★
()


ну индекс то тебе все равно придётся делать. а уж как потом доставать данные - через read() или через отображаемые файлы - это уже не важно. все равно в кеш полезешь.

// wbr

klalafuda ★☆☆
()

А что, без индекса совсем никак? Разве нельзя сделать, чтобы обращение к myclassarr[n] выглядело так:

double getv(int n)
{
  double vv;
  file.seekg(0); //перемещаемся в начало файла
  for(int i=0;i<n;++i) file >> vv; //читаем n слов
  return vv; //и возвращаем последнее прочитанное слово
}

Медленнее, конечно, но во-первых память под индекс не надо выделять, а во-вторых задача учебная просто.

Obey-Kun ★★★★★
() автор топика

Тут все зависит от использования. Если в подавляющем большинстве случаев планируется последовательный доступ (ну циклы там и т.п.), то лучше мапать максимальными кусками, если же доступ будет произвольным, то лучше мапать небольшими кусками, в памяти хранить наиболее используемые куски (те, к которым обращаются чаще всего)

maverik ★★
()

И да, можно вообще B+ деревья использовать.

maverik ★★
()
Ответ на: комментарий от maverik

Оптимизация вообще не интересует. Хотелось бы, чтобы оно вытаскивало N-ное слово просто вернувшись в начало файла и отсчитав бы N слов (то бишь N раз сделав file >> tmp)

Obey-Kun ★★★★★
() автор топика

1. Это надо было в девелопмент постить, а не в толксы.

2. Идеи "надо файл замаппить, а не seek-ать" мне непонятны. Ядро кэширует вокруг того, что сикнуто, разве не так?

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Obey-Kun

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

A2K
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.