C Программирование чтения / записи файлов - PullRequest
20 голосов
/ 04 декабря 2010

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

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

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

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

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

Ответы [ 5 ]

14 голосов
/ 04 декабря 2010

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

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

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

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

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

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

  2. Как быстро вы должны иметь доступ к данным? Важен ли доступ в реальном времени? Это особенно большой или сложный набор данных, который может занять слишком много времени для загрузки с жесткого диска по требованию? Какую производительность ожидают ваши пользователи?

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

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

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

И, как намекает эта последняя точка, что-то сбалансированного или комбинированного подхода, вероятно, примерно так же близко, как вы найдете «идеальное» решение.Вы можете хранить как можно больше данных в ОЗУ, периодически записывая любые изменения или модификации в файл на диске во время состояния бездействия вашего приложения.В среднем программа тратит время на ожидание, чтобы пользователь что-то сделал, а не наоборот.Вы можете воспользоваться этими простоями циклов ЦП, чтобы сбросить данные, хранящиеся в памяти, обратно на диск без какого-либо заметного снижения скорости.Этот подход постоянно используется в разработке программного обеспечения и помогает избежать ошибок, на которые указывает ответ EClaesson.Если ваше приложение аварийно завершает работу или неожиданно завершает работу, вероятно, будет потеряна только очень небольшая часть данных, поскольку большая часть из них уже записана на диск за сценой.: Конечно, ответ Dark Falcon правильный, что в производственном приложении вы, скорее всего, будете использовать что-то вроде базы данных для обработки данных.Но поскольку это, по-видимому, для образовательных целей, я думаю, что понимание основных компромиссов, стоящих за каждым подходом, гораздо важнее.

5 голосов
/ 04 декабря 2010

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

  1. Требуется ли одновременный доступ к нему нескольких пользователей?
  2. Требуется ли к нему доступ с нескольких машин?

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

2 голосов
/ 04 декабря 2010

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

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

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

2 голосов
/ 04 декабря 2010

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

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

1 голос
/ 04 декабря 2010

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

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

...