Подтвердить что ты не робот

C Программирование чтения/написания файлов

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

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

Мое решение этой проблемы перед тем, как программа откроет свое меню, я прочитал все записи внутри и сохранил их в массиве []. При этом я мог бы манипулировать всеми записями. Затем перед выходом пользователя из программы я сохраняю его в том же файле и перезаписываю все записи на нем.

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

Обе наши работы, конечно, можно закодировать. Но мне интересно, что более эффективно и эффективно использовать, если мы имеем дело с тысячами или миллионами записей. Или другие решения лучше, чем мы. Возможно, вы могли бы поделиться с нами опытом обработки файлов... Спасибо.

4b9b3361

Ответ 1

Это классический случай, с которым вы снова и снова столкнетесь в программировании: оптимизируюсь для скорости или использования памяти?

И, как и все подобные головоломки, нет "правильного" ответа или идеального решения. Другими словами, вы и ваш одноклассник правы в ваших решениях проблемы.

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

В противоположность этому ваш одноклассник сохраняет ОЗУ, ожидая загрузки данных по требованию с жесткого диска. Но это будет стоить ей: попадание на жесткий диск - очень дорогостоящий процесс по сравнению с извлечением данных, которые уже хранятся в памяти, и она будет делать это каждый раз, когда пользователь внесет изменения. Подумайте, сколько времени потребуется для запуска программы или перехода на уже открытую.

И в этом заключается компромисс. Некоторые из важных вещей, чтобы задать себе здесь:

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

  • Насколько быстро вам нужно иметь доступ к данным? Доступен ли доступ в режиме реального времени? Является ли это особенно большим или сложным набором данных, который будет слишком долго загружаться с жесткого диска по запросу? Какую производительность ожидают ваши пользователи?

  • Какая система предназначена для вашего приложения? Иногда встроенные системы и другие специальные случаи требуют своих уникальных подходов к проектированию. У вас может быть избыток оперативной памяти и очень ограниченное количество фиксированного хранилища, или вы можете иметь прямо противоположное. Если вы используете стандартное, современное оборудование для ПК, что ваши пользователи хотят/нужны/уже есть? Если большинство ваших целевых пользователей уже используют относительно "мускулистые" аппаратные средства, вы можете принимать различные проектные решения, чем если бы вы нацелились на более широкую потенциальную аудиторию - вы наверняка видели, что эти компромиссы были явно выражены до того, как программа выражала систему требования.

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

  • Существуют ли определенные части ваших данных, к которым обращаются чаще, чем другие? Подумайте о том, чтобы хранить эти конкретные части всегда в памяти и лениво загружать остальное (что означает, что вы пытаетесь только извлечь их в память, когда/если они доступны пользователю).

И как подсказки последнего момента, что-то вроде сбалансированного или комбинированного подхода, вероятно, примерно так же близко, как вы придете к "идеальному" решению. Вы можете хранить как можно больше данных в ОЗУ, периодически записывая любые изменения или модификации обратно в файл на диске во время ожидания вашего приложения. Там много времени, которое средняя программа тратит на пользователя, чтобы что-то делать, а не наоборот. Вы можете использовать эти холостые циклы процессора, чтобы вымыть вещи, хранящиеся в памяти, обратно на диск, не прибегая к заметному снижению скорости. Этот подход используется все время в разработке программного обеспечения и помогает избежать ошибок, отмеченных ответом EClaesson. Если ваше приложение аварийно завершает работу или неожиданно завершает работу, только очень небольшая часть данных, вероятно, будет потеряна, поскольку большая часть из них уже была привязана к диску за кулисами.

Постскриптум: Конечно, ответ Dark Falcon верен, что в производственном приложении вы, скорее всего, будете использовать что-то вроде базы данных для обработки данных. Но поскольку это, по-видимому, для образовательных целей, я думаю, что понимание основных компромиссов за каждым подходом гораздо важнее.

Ответ 2

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

  • Нужно ли одновременно обращаться к нескольким пользователям?
  • Нужно ли получать доступ с нескольких компьютеров?

Наиболее распространенным вариантом для хранения значительного объема информации будет база данных на базе SQL, такая как MySQL, Postgres, Microsoft SQL Server, SQLite и т.д. Они в основном напоминают ваше решение одноклассника больше, чем ваше.

Ответ 3

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

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

Ответ 4

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

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

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

Ответ 5

Редактирование записей на месте является тонким, если они не имеют фиксированного размера. Это возможно только с двоичным форматом и поддержкой для маркировки строки как неиспользуемой (например, с внешним индексом или с исключениями). Файловые системы не являются атомарными, поэтому вы не можете быть уверены, что все, что вы делаете, полностью на диске.

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