Много вопросов о файловом вводе / выводе (чтение / запись строк сообщения) - PullRequest
3 голосов
/ 12 апреля 2010

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

Сначала я разработал свои структуры данных для хранения ВСЕХ сообщений в связанном списке, ограничив размер сообщения до 256 символов. Тем не менее, я думаю, что мои преподаватели предпочтут, если я сохраню сообщения на диске и читаю их только тогда, когда они мне нужны. Конечно, они не скажут, что они предпочитают, мне нужно сделать выбор и объяснить как можно лучше, почему я пошел по этому пути.

Следует помнить, что мне нужно сохранять только последние 20 сообщений от каждого пользователя, не более.

Прямо сейчас у меня есть Хеш-таблица, которая будет действовать как входящая, она будет внутри профиля пользователя. Эта хеш-таблица будет проиндексирована по имени (пользователь, отправивший сообщение). Значением для каждого элемента будет структура данных, содержащая массив size_t с 20 элементами (20 сообщений, как я сказал выше). Идея состоит в том, чтобы отслеживать смещения файлов на диске и записанные байты. Затем, когда мне нужно прочитать сообщение, мне просто нужно использовать fseek() и прочитать необходимые байты.

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

Однако это создает проблему ... Так как мне нужно сохранить только последние 20 сообщений, мне нужно удалить старые, когда я достигну этого предела.

Я понятия не имею, как это сделать ... Все, что я знаю, это о fread() и fwrite() для чтения / записи байтов из / в файлы. Как я могу перейти к смещению файла и сказать «эй, удалите следующие байты X»? Даже если бы я мог сделать это, есть другая проблема ... Все смещения ниже этого будут совершенно разными, и мне придется обработать все почтовые ящики пользователей, чтобы решить эту проблему. Что было бы больно ...

Итак, есть предложения по решению моих проблем? Что вы предлагаете?

Ответы [ 3 ]

2 голосов
/ 12 апреля 2010

Вы не можете произвольно удалять байты из середины файла; единственный способ - переписать весь файл без них. Не обращая внимания на вопрос о том, стоит ли так поступать, если у вас есть поля фиксированной длины, одним из решений будет просто перезаписать самое старое сообщение самым новым; таким образом, размер / положение сообщения на диске не изменяется, поэтому не затрагиваются другие смещения.

Редактировать: Если вам разрешено использовать внешние библиотеки, хорошим решением может стать простой SQLite db.

0 голосов
/ 18 февраля 2013

Я хочу предложить другое решение для полноты:

Строки должны заканчиваться нулевым байтовым символом, "hello world\0", поэтому вы можете читать необработанные двоичные данные до достижения "\0". Другие типы данных имеют фиксированные биты, остерегайтесь байтереров (порядковый номер).

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

"11hello world;2hi;15my name is loco"

Это позволяет обрабатывать необработанные фрагменты как поля данных.

0 голосов
/ 12 апреля 2010

Ты усложняешь свою жизнь намного больше, чем нужно.

Если ваши сообщения состоят из 256 символов, то для хранения каждого сообщения используйте массив из 256 символов.

Запишите его на диск с помощью fwrite, прочитайте с помощью fread, удалите его, изменив первый символ строки на \ 0 (или что-то еще, что вам нравится) и запишите его на диск.

Храните индекс сообщений в простой структуре (имя пользователя / recno) и перемещайтесь по файлу с помощью fseek. Вы можете либо перебором следующей свободной записи при записи новой записи (начать чтение в начале файла и прекратить при нажатии на \ 0), либо сохранить индекс свободных записей в массиве и получить одну из них при записи новый (или, если ваш массив пуст, затем найдите конец файла и напишите новую запись полностью).

...