Название: Обращение к данным по индексу Отправлено: Pixel от Сентябрь 12, 2012, 14:02 Прочитал статью, про работу с данными в Qt и возник вопрос. Можно ли обращаться к конкретным данным, не читая при этом весь кусок файла, идущий перед нужными данными. Как я понял это работа с базами данных, но вразумительной статьи про них я не нашел. Подскажите, если не сложно, простенький способ обратиться к нужному куску данных или статейку про работе с БД для новичков.
Название: Re: Обращение к данным по индексу Отправлено: mutineer от Сентябрь 12, 2012, 14:05 Про какие данные ты говоришь? Где они лежат? Если ты про чтение из файла, то есть метод seek()
Название: Re: Обращение к данным по индексу Отправлено: Pixel от Сентябрь 12, 2012, 14:17 двоичные данные. Пример: есть структура с данными. Нужно сохранить много таких структур и записать в файл. Далее нужно будет обращаться к конкретной структуре, зная ее индекс или адрес или что угодно, что позволило бы обратиться к этой структуре, не считывая предыдущие.
Название: Re: Обращение к данным по индексу Отправлено: mutineer от Сентябрь 12, 2012, 14:23 seek тебе в помощь
Название: Re: Обращение к данным по индексу Отправлено: Pixel от Сентябрь 12, 2012, 14:29 Можно по подробней? чей это метод? QDataStream? QFile? Другой?
как его использовать? Нашел такой метод в QFile. Ну вот допустим я узнал, что по индексу 3 есть запись. Как мне теперь обратиться к структуре под номером 3? Название: Re: Обращение к данным по индексу Отправлено: Serr500 от Сентябрь 12, 2012, 14:34 Сначала QFile::seek. Если вернуло true, то QFile::read.
P.S. RTFM! Название: Re: Обращение к данным по индексу Отправлено: mutineer от Сентябрь 12, 2012, 14:41 Можно по подробней? чей это метод? QDataStream? QFile? Другой? как его использовать? Нашел такой метод в QFile. Ну вот допустим я узнал, что по индексу 3 есть запись. Как мне теперь обратиться к структуре под номером 3? Методом seek пропустить первые две структуры (2 * размер структуры в байтах) и вычитать третью Название: Re: Обращение к данным по индексу Отправлено: Serr500 от Сентябрь 12, 2012, 14:48 mutineer
А щас он захреначит в файл class через QFile::write(this, sizeof(*this)) вместе с VMT и будет удивляться, почему оно падает. ;) Название: Re: Обращение к данным по индексу Отправлено: Pixel от Сентябрь 12, 2012, 15:09 Честно говоря, я пока вообще не могу понять как и что можно записывать. Во всех примерах, что я читаю работают только с дата стримом, и ничего кроме этого:
struct str { QString name; }; ... QFile file("base.txt"); file.open(QIODevice::WriteOnly); str dat; dat.name="name"; QDataStream in(&file); in<<dat.name; у меня сделать не получается. Метод Write я вообще не понял как работает. Из документации: write ( const char * data, qint64 maxSize ) второй аргумент это размер первого, а вот что в первом указывать я не понял. Структуру нельзя, данные структуры нельзя. Как что то туда записать? Название: Re: Обращение к данным по индексу Отправлено: Bepec от Сентябрь 12, 2012, 15:30 Смотрим. Есть метод write ( const QByteArray & ) допустим.
Значит нам что надо сделать ? Правильно - запихать в QByteArray структуру, записать эту структуру. На обратной стороне (ты знаешь размер структуры) считать данные из QByteArray в том же порядке. С QDataStream в принципе так же. PS % на 70 уверен что это сработает. Ибо в последний раз сериализовал через Qt очень давно :D Название: Re: Обращение к данным по индексу Отправлено: Serr500 от Сентябрь 12, 2012, 15:33 С QDataStream в принципе так же. Ему ещё позиционирование нужно и, скорее всего, нелинейное (вперёд-назад). А QDataStream позиционирование не поддерживает (только вперёд). Поэтому придётся брать QFile.Название: Re: Обращение к данным по индексу Отправлено: xokc от Сентябрь 12, 2012, 15:43 Давай сюда описание своей структуры. Запишем её в файл.
Название: Re: Обращение к данным по индексу Отправлено: Igors от Сентябрь 12, 2012, 15:55 А щас он захреначит в файл class через QFile::write(this, sizeof(*this)) вместе с VMT и будет удивляться, почему оно падает. ;) Так это неизбежный этап познания :)Метод Write я вообще не понял как работает. Этот метод предназначен для сохранения низкоуровневых данных, когда сохраненный на диске образ совпадает (байт в байт) с представлением объекта в памяти. Для чуть более сложного объекта (ну хоть QString) такое read/write не проходит, записанные данные не удается прочитать. Из документации: write ( const char * data, qint64 maxSize ) второй аргумент это размер первого, а вот что в первом указывать я не понял. Структуру нельзя, данные структуры нельзя. Как что то туда записать? Я предлагаю такое решение: пишете через QDataStream, используя удобные операторы <<. По ходу дела запоминаете позицию и размер записи напр так Код Теперь читаем nth запись Код
Edit: ну разумеется это предполагает что все записи одного размера. Если это не так то надо создавать массив/контейнер theDataStart Название: Re: Обращение к данным по индексу Отправлено: Pixel от Сентябрь 12, 2012, 16:06 Всем спасибо! вроде как получилось. Вот:
QFile file("base.txt"); file.open(QIODevice::WriteOnly); str dat, dat2; dat.name="name"; QByteArray arr; arr.resize(sizeof(dat)); memmove(arr.data(), &dat, sizeof(dat)); file.write(arr, sizeof(dat)); file.close(); arr.clear(); file.open(QIODevice::ReadOnly); if (file.seek(0)) { arr=file.read(sizeof(dat)); memmove(&dat2, arr.data(), sizeof(dat)); } qDebug()<<dat2.name; Как то так. Выводит: "name". Посмотрите, такой способ корректен, ничего не напутал не намудрил?) Название: Re: Обращение к данным по индексу Отправлено: Igors от Сентябрь 12, 2012, 16:11 Как то так. Выводит: "name". Посмотрите, такой способ корректен, ничего не напутал не намудрил?) Mда, видимо в естественный процесс эволюции лучше не вмешиваться :)Пользуйтесь тегом для обрамления кода Название: Re: Обращение к данным по индексу Отправлено: Пантер от Сентябрь 12, 2012, 16:14 Пациент скорее мёртв, чем жив....
Название: Re: Обращение к данным по индексу Отправлено: xokc от Сентябрь 12, 2012, 16:16 Посмотрите, такой способ корректен, ничего не напутал не намудрил?) Намудрил так, что даже странно, что не попутал.Код
Запись в файл: Код
Чтение из файла: Код
Название: Re: Обращение к данным по индексу Отправлено: Serr500 от Сентябрь 12, 2012, 20:24 Е... мой старый ... !!!
Код: str dat; Название: Re: Обращение к данным по индексу Отправлено: Pixel от Сентябрь 12, 2012, 20:43 xokc, это я все знаю, стандартная запись через поток. А как мне считать структуру из середины не прочесывая предыдущие?
Serr500, вы пишите намеками. Я только начал изучать Qt, я их не понимаю. Сложно что ли написать пример как сделал это господин xokc, только по сабжу? Если лень, то дайте хотя бы ссылку на статью, только на ту, которая мне объяснит мою проблему, а не просто "работа с данными на Qt". Таких я уже прочитал уйму, но ни в одной не решается моя проблема, иначе я бы сюда не обращался. Название: Re: Обращение к данным по индексу Отправлено: Serr500 от Сентябрь 12, 2012, 20:51 Serr500, вы пишите намеками. Я только начал изучать Qt, я их не понимаю. Вы не понимаете не Qt, а основы языка C++.Сложно что ли написать пример как сделал это господин xokc, только по сабжу? А зачем? Господин xokc уже всё написал.xokc, это я все знаю, стандартная запись через поток. А как мне считать структуру из середины не прочесывая предыдущие? У Вас вдобавок к незнанию Qt и C++ ещё и невнимательность:Я предлагаю такое решение: пишете через QDataStream, используя удобные операторы <<. По ходу дела запоминаете позицию и размер записи напр так Объедините то, что написали xokc и Igors и задача будет решена.Код: ... // открыли файл для записи Код: void ReadRecNo( QDataStream & strm, int recNo, MyData & theData ) Edit: ну разумеется это предполагает что все записи одного размера. Если это не так то надо создавать массив/контейнер theDataStart Название: Re: Обращение к данным по индексу Отправлено: V1KT0P от Сентябрь 12, 2012, 20:53 xokc, это я все знаю, стандартная запись через поток. А как мне считать структуру из середины не прочесывая предыдущие? Все зависит от условий задачи.Serr500, вы пишите намеками. Я только начал изучать Qt, я их не понимаю. Сложно что ли написать пример как сделал это господин xokc, только по сабжу? Если лень, то дайте хотя бы ссылку на статью, только на ту, которая мне объяснит мою проблему, а не просто "работа с данными на Qt". Таких я уже прочитал уйму, но ни в одной не решается моя проблема, иначе я бы сюда не обращался. Например если у нас структура фиксированного размера и необходимо один раз записать и потом считывать, то для доступа к структуре перемещаемся в файле в позицию РАЗМЕР_СТРУКТУРЫ * НОМЕР_СТРУКТУРЫ. Если структуры не фиксированного размера, но опять-же нам надо один раз записать и потом считывать, то заводим два файла, в первый тупо по порядку складываем структуры, а во второй смещение каждой структуры. В результате для доступа к структуре переходим во втором файле в позицию НОМЕР_СТРУКТУРЫ * РАЗМЕР_СМЕЩЕНИЯ_СТРУКТУРЫ и читаем оттуда переменную СМЕЩЕНИЕ_СТРУКТУРЫ размером РАЗМЕР_СМЕЩЕНИЯ_СТРУКТУРЫ. Далее переходим в первом файле в позицию СМЕЩЕНИЕ_СТРУКТУРЫ и считываем структуру. Если же надо еще и добавлять/удалять/изменять то лучше ищи готовую библиотеку, ибо ты для более сложных вещей еще не готов. Название: Re: Обращение к данным по индексу Отправлено: Serr500 от Сентябрь 12, 2012, 20:57 Pixel, вот вам задачка на знание языка C++ (не Qt!):
Код: struct Struct Название: Re: Обращение к данным по индексу Отправлено: Igors от Сентябрь 12, 2012, 22:45 Если структуры не фиксированного размера, но опять-же нам надо один раз записать и потом считывать, то заводим два файла, в первый тупо по порядку складываем структуры, а во второй смещение каждой структуры. В результате для доступа к структуре переходим во втором файле в позицию НОМЕР_СТРУКТУРЫ * РАЗМЕР_СМЕЩЕНИЯ_СТРУКТУРЫ и читаем оттуда переменную СМЕЩЕНИЕ_СТРУКТУРЫ размером РАЗМЕР_СМЕЩЕНИЯ_СТРУКТУРЫ. Далее переходим в первом файле в позицию СМЕЩЕНИЕ_СТРУКТУРЫ и считываем структуру. Что-то уж очень тупо таскать/сбивать 2 файла :) Лучше все в одном с TOC как напр это было в wad файлахЕсли же надо еще и добавлять/удалять/изменять то лучше ищи готовую библиотеку, ибо ты для более сложных вещей еще не готов. Ну не надо "надувать щеки", там ничего сложного :)Название: Re: Обращение к данным по индексу Отправлено: V1KT0P от Сентябрь 12, 2012, 23:15 Что-то уж очень тупо таскать/сбивать 2 файла :) Лучше все в одном с TOC как напр это было в wad файлах Это для "нас" ничего сложного, а у автора топика вызывает сложность даже банальная запись текста в файл.Ну не надо "надувать щеки", там ничего сложного :) Название: Re: Обращение к данным по индексу Отправлено: xokc от Сентябрь 13, 2012, 08:52 xokc, это я все знаю, стандартная запись через поток. А как мне считать структуру из середины не прочесывая предыдущие? Если Вы собираетесь записывать в файл структуры разных размеров (а я надеюсь, что Вы понимаете, что размеры данных, находящихся в тех структурах, которые Вы нам показали будут разными в зависимости от длинны строки), то простого решения для обеспечения прямого доступа к данным в файле не получится. Если нужно использовать только один файл и нельзя использовать готовые решения, то я бы делал в начале файла область для индексов, где указывал бы откуда надо читать данные. Но это уже совсем другая задача. Никто за Вас тут её решать не будет. |