C прочитать ini файл

Обновлено: 04.07.2024

Компонент для работы с ini-файлом

При разработке одной из программ я столкнулся с совершенно типовой проблемой: было необходимо использовать ini-файл для хранения конфигурационных данных программы. Задача стандартная, но в моем случае данные были совершенно разных типов (целые числа, числа с плавающей точкой, строки, цвет в кодировке RGB). Каждый из параметров должен был удовлетворять определенным ограниченям. Подходящих решений под рукой не оказалось, в связи с чем на свет появился этот компонент.

Терминология

Для начала, давайте определимся с используемой терминологией. Ini-файл – текстовый файл, содержащий записи о конфигурации программы. Для удобства он разбит на секции. Секция – это именованная совокупность параметров. Секция начинается с имени секции. Имя секции должно быть заключено в угловые скобки и может содержать любые символы (за исключением символов ‘[‘ и ‘]’). Секция содержит произвольное количество параметров. Параметр это строка вида key=value, где key – это ключ, а value – значение, сопоставленное с этим ключом. Ключ и значение могут содержать любые символы (за исключением символа ‘=‘). Строка, начинающаяся с символа ‘;’ считается комментарием и пропускается.

ПРИМЕЧАНИЕ

Пробельные символы вокруг ключа и параметра игнорируются (т.е. строка вида “ key = value “ будет сведена к строке “key=value”).

ПРИМЕЧАНИЕ

Префиксный и постфиксный символы для имени группы задается константами IniParser::chSectPrefix и IniParser::chSectPostfix.

Возможности

  • сохранение / чтение данных из ini-файла
  • произвольное количество секций и параметров
  • поддержка параметров произвольного типа
  • возможность наложения ограничений на каждый параметр в отдельности
  • возможность определения «обязательности» параметра
  • корректная обработка всех ошибок
  • простота и удобство в работе

Краткое описание компонента

Все классы компонента полностью реализованы на языке C++ с использованием исключительно библиотеки STL (за исключением класса CRGBValue, в котором был использован Windows’овский тип данных COLORREF), что позволяет использовать данный компонент как в DOS’овских так и любых в Win16/32 приложениях. Все классы компонента помещены в пространство имен IniParser. Компонент включает в себя следующие классы:

Основные классы

CParserпредставляет основную функциональность по работе с ini-файлами
CSectionпредставляет секцию ini-файла
CParameterпредставляет параметр
CExceptionпредставляет исключение

Классы, представляющие типы данных

CCommonValueПредставляет абстрактный тип данных. Является базовым классом для всех классов, представляющих какие-либо типы данных.
CNumericTypesШаблон. Представляет значения числовых типов (int, float, double. ).
CRangeLimitsШаблон. Представляет ограничения на значения числовых типов. Используется только совместно с шаблоном CNumericTypes.
CStdStringValueПредставляет строковое значение (строка STL – std::string).
CStringValueПредставляет строковое значение (стандартная C-строка (char *) с известной длиной).
CRGBValueПредставляет цвет в кодировке RGB.
CBoolValueПредставляет значения булевского типа.

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

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

Использование (Быстрый старт)

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

ПРЕДУПРЕЖДЕНИЕ

Имена секций и параметров не должны содержать русских букв и символа ‘=’.

1. Скопируете файлы компонента (IniParser.cpp и IniParser.h) в папку к вашему проекту, добавьте их в проект.

2. Добавьте в файл stdafx.h следующие строки

3. Определить структуру будущего ini-файла, тип, диапазоны допустимых значений и обязательность для каждого параметра. Допустим, что наш ini-файл имеет следующую структуру:

4. Объявить в удобном месте (например, в классе) переменные, соответствующие параметрам

5. Создать объект класса IniParser::CParser

6. Сформировать структуру ini-файла, используя классы IniParser::CParameter и IniParser::CSection, методы IniParser::CParser::AddSection и IniParser::CSection::AddParameter.

7. Вызвать один из методов класса IniParser::CParser для считывания или сохранения данных. И не забывать про обработку исключений!

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

Подробное описание компонента и входящих в него классов

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

ПРИМЕЧАНИЕ

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

Основные классы

Класс CParser

Назначение: предоставляет основную функциональность по работе с ini-файлами.

bAllowInvalidStringsопределяет поведение в случае обнаружения неверной (не являющейся именем секции или параметром) строкиtrue – пропустить
false - возбудить исключение
bAllowUnkSectionsопределяет поведение в случае обнаружения неизвестной секцииtrue – пропустить
false - возбудить исключение
bAllowUnkKeysопределяет поведение в случае обнаружения неизвестного ключаtrue – пропустить
false - возбудить исключение

void ParseFile (const char *pchFilePath) throw (CException *);Читает данные из ini-файла в связанные переменные, в случае ошибок выбрасывает исключение.
void StoreToFile(const char *pchFilePath) const throw (CException *);Сохраняет данные из связанных переменных в ini-файл, в случае ошибок выбрасывает исключение.
void ParseStream(std::istream &rStream) throw (CException *);Читает данные из потока в связанные переменные, в случае ошибок выбрасывает исключение.
void StoreToStream(std::ostream &rStream) const throw (CException *);Сохраняет данные из связанных переменных в поток, в случае ошибок выбрасывает исключение.

CSection *AddSection(const char *pchSectionName);Добавляет секцию. Возвращает указатель на добавленную секцию.
bool RemoveSection(const char *pchSectionName);Удаляет секцию по имени (без префиксного и постфиксного символов), в случае успеха возвращает true.
void RemoveAllSections();Удаляет все секции и освобождает связанную с ними память.
CSection *GetSection(const std::string &rString) const;CSection *GetSection(const char *pchString) const;Возвращает секцию по её имени.

TSectionsConstIt GetSectionsBegin() const;Возвращает итератор на начало списка секций.
TSectionsConstIt GetSectionsEnd() const;Возвращает итератор на конец списка секций.

std::ostream& operator<<(std::ostream& stream, const CParser &pars);Выводит данные из связанных переменных в поток, в случае ошибок выбрасывает исключение.

Данный код выведет ini-файл в стандартный поток вывода. std::istream& operator>>(std::istream& stream, CParser &pars);Читает данные из потока в связанные переменные, в случае ошибок выбрасывает исключение.

Класс CSection.

Назначение: представляет секцию ini-файла

void AddParameter(const char *pchKey, CCommonValue *pValue, bool bMandatory = false);Добавляет параметр в секцию.
pchKey – константный указатель на строку, содержащую имя ключа
pValue – указатель на объект значения
bMandatory – определяет обязательность параметра (true – обязательный, false – нет).
Если при разборе файла обязательный параметр не найден, возбуждается исключение.
Объект, на который указывает pValue будет удален в деструкторе класса CSection.

Класс CParameter.

Назначение: представляет параметр

const std::string &GetKey() const;Возвращает ключ
const CCommonValue *GetValue() const;Возвращает константный указатель на объект значения
std::string ToString() const throw (CException *);Возвращает строковое представление параметра

Обработка ошибок и класс CException

При возникновении ошибочной ситуации при чтении или сохранении ini-файла генерируется исключение. Исключение представлено классом CException. В обработчике исключения можно узнать номер строки файла, при работе с которой произошло исключение, код ошибки, и указатель на объект класса CParameter (он может быть NULL). Возможные коды ошибок прописаны в перечислении TErrorCodes, вот они:

FileSystemErrorОшибка файловой системы. Метод GetLineNum() класса CException будет содержать возвращать код ошибки.
UnknownSectionНеизвестная секция.
UnknownParameterНеизвестный параметр.
InvalidStringНеверная строка.
InvalidValueНеверное значение (ошибка преобразования).
ValueOutOfRangesЗначение не соответствует наложенным ограничениям.
ParameterAlreadyDefinedПараметр определен несколько раз.
MissingMandatoryParamОтсутствует обязательный параметр.

Методы класса CException:

int GetLineNum() const;Возвращает номер строки файла, при работе с которой произошла ошибка.
TErrorCodes GetCode() const;Возвращает код ошибки.
const CParameter *GetParameter() const;Возвращает указатель на объект класса CParameter.

Во избежании утечки памяти в обработчике catch следует удалить объект исключения вызвав метод CException::Delete().

Работа с собственными типами данных и класс CCommonValue

Класс CCommonValue

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

virtual void Parse(const std::string &rString) throw (CException *) = 0;Пытается пребразовать содержимое строки rString в значение определенного типа, в случае неудачи выбрасывает исключение.
virtual std::string ToString() const throw (CException *) = 0;Возвращает строковое представление значения
virtual bool IsSatisfy() const = 0;Проверяет состояние объекта и возвращает true, если в связанной переменной находится корректное (удовлетворяющее ограничениям) значение

Классы, представляющие типы данных

Шаблон CNumericTypes<T>

Назначение: представляет значения числовых типов (int, float, double. )

pDataУказатель на переменную типа T, в которую будут записываться/считываться значения
pLimitsУказатель на экземпляр класса CNumericType::CRangeLimits, с помощью которого задаются ограничения на значение. Если ограничений нет, то pLimits д.б. равен NULL.
Объект, на который указывает, pLimits будет удален в деструкторе шаблона CNumericType.
flagsФлаги форматирования. Допустимы следующие значения флагов:
dec – десятичное число (только целые числа)
hex – шестнадцатеричное число (только целые числа)
oct – восьмеричное число (только целые числа)
scientific – число выводится в научном формате (только числа с плавающей точкой)
fixed – число выводится в фиксированном формате (только числа с плавающей точкой)
nPrecisionТочность (количество знаков после запятой)

Шаблон CRangeLimits<T>

Назначение: представляет ограничения на значение

limВид ограничения, может принимать следующие значения:
CRangeLimits::MinMax – ограничение сверху и снизу
CRangeLimits::Min – ограничение снизу
CRangeLimits::Max – ограничение сверху
minМинимально допустимое значение
maxМаксимально допустимое значение
ПРЕДУПРЕЖДЕНИЕ

Параметр у шаблона CRangeLimits должен быть таким же как и у шаблона CNumericTypes.

Класс CStdStringValue

Назначение: представляет строковое значение (строка STL - std::string)

pstrDataАдрес строки std::string, по которому будет записываться/читаться значение.
nMaxLenМаксимальная длина строки, если == -1, то длина не ограничена.
bAllowEmptyЕсли равен true, то допускаются пустые строки.

Класс CStringValue

Назначение: представляет строковое значение (стандартная C-строка с известной длиной)

pchDataАдрес строки char *, по которому будет записываться/читаться значение.
nMaxLenМаксимальная длина строки
bAllowEmptyЕсли равен true, то допускаются пустые строки.

Класс CRGBValue

Назначение: представляет цвет записанный в кодировке RGB

pColorАдрес переменной типа COLORREF, по которому будет записываться/читаться значение

Класс CBoolValue

pbDataАдрес переменной типа bool, по которому будет записываться/читаться значение
styleОпределяет используемый стиль. Существует два стиля:
TrueFalse – при этом значение может быть “true” либо “false”
YesNo – при этом значение может быть “yes” либо “no”

Заключение

Благодарности

Автор выражает благодарность всем участникам форумов RSDN, отвечавших на его вопросы.

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

На хабре уже была посвящена этому тема, поэтому… перейти

Информация о Properties.Settings

Организация Properties.Settings — это обычный xml файл, который можно найти в папке пользователя:

С:\ Users \ [user name] \ AppData \ Local \ [ (Project Name) or (AssemblyCompany) ] \ [name project_cashBuild] \ [AssemblyVersion] \ user.config

Для начала нам нужно создать такие переменные для Properties.Settings. Перейдем в Properties -> Settings.settings:



Я создал 3-и переменные и выбрал область их использования: 2- область пользователь и 1- приложение.

Различие между областями просты. Область приложения можно только читать, а пользователь — изменять и читать.

Вернемся к переменным:

  • Version — версия нашей программы. Определил ее строкой и областью приложение. Т.к. версия может содержать буквы (например, b — от beta). А область выбрал, чтоб не менялась наша версия приложения (т.к. AssemblyVersion редко кто использует).
  • Save_text — это переменная, куда мы будем сохранять наш текст.
  • open_sum — сколько раз мы открыли программу.

Результаты работы программы

Первый запуск, мы видим, что кол-во запусков равно 1. И теста в richTextBox1 нет.


Теперь напишем и сохраним текст.


При втором запуске мы видим, что текст сохранен, и кол-во запусков уже 2-ва.


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

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

Теперь перейдем к нашей теме. Для работы с таким типом файлов, нам нужно создать класс по работе с ним. Создаем класс, например «IniFile», подключаем пространство имен, которых нет:


А теперь разбираем по-порядку:

Теперь переходим в основную программу.

Результаты работы программы

При первом запуска, у нас нет файла config.ini. Поэтому при проверке возвращаются fasle и мы приравниваем окно к минимальным параметрам.


Меняем параметры окна и жмем «Применить»


Редактируем файл config.ini руками и жмем загрузить.


На этом все, в следующий раз опишу работу с xml файлами и с бинарными файлами.

Как лучше и проще реализовать работу с ini файлами ? Именно интересует реализация структуры:

Можно ведь написать парсер использую функция для работы с файлами ? P.S. Не предлагайте готовые решения, кроме встроенных функций, т.к. хочется самому.

737 2 2 золотых знака 17 17 серебряных знаков 30 30 бронзовых знаков ini - неудобный устаревший формат, лучше сразу берите xml или json У меня есть программа, которая хранит изменяемые параметры, как захочет пользователь. Что мне теперь использовать xml или json ? и это тут вообще ни причем. Тем более - "отучаемся говорить за всех". Впрочем, под Windows - наверняка у вас имеется какой-нибудь php.ini или инишник mysql, посмотрите туда. И то, что у вас нет /etc никак не делает формат ini устаревшим или неудобным.

Вот ещё, pure C: iniparser. Умеет понимать довольно сложные случаи (документация).

Максимальная длина строки фиксирована, но её можно переопределить при сборке:

P.S. Что-то мне его допилить уже захотелось.

" [Section] Keyword = value ; comment is converted to the following key pair: ("section:keyword", "value") " - разве это правильно? В таком варианте значения заведомо не могут содержать точку с запятой, что выглядит как-то бредово. Никто не мешает заключать значения в кавычки. Там других мелочей есть немного, в самой реализации.

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

Если вы пишете для Windows и можете использовать WinAPI, тогда вы можете воспользоваться функциями GetPrivateProfileString и GetPrivateProfileInt .

Если вы пишете кроссплатформенно и готовы использовать Boost, то просто возьмите Program_options.

Если вы хотите полностью реализовать парсер самостоятельно, посмотрите для вдохоновения проект inih. Лучше чем там написано, всё равно никто не напишет.

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

Однако доступны сторонние решения.

Мне нравится старый метод (P / Inovke), и вы можете использовать юникод со старым методом, например: File.WriteAllBytes (путь, новый байт [] <0xFF, 0xFE>); Хорошая упаковка, но могло быть и лучше. Он не может полностью проанализировать значение, содержащее '=' или '\ n'

Предисловие

Крошечный класс

Добавьте в проект новый класс IniFile.cs :

Как это использовать

Откройте файл INI одним из трех способов:

Вы можете записать некоторые значения так:

Чтобы создать такой файл:

Чтобы прочитать значения из файла INI:

При желании вы можете установить [Section] :

Чтобы создать такой файл:

Вы также можете проверить наличие такого ключа:

Удалить ключ можно так:

Вы также можете удалить весь раздел (включая все ключи) следующим образом:

Не стесняйтесь комментировать любые улучшения!

Я немного опоздал, но отсутствует метод GetSections() . Возможно, более традиционным вариантом по умолчанию были бы файлы .ini для каждого приложения (а не для каждой сборки), такие как Path.GetFullPath(IniPath ?? Path.ChangeExtension(Application.ExecutablePath, ".ini")) . Сейчас она устарела и насколько я уважаю Рэймонда Чена, многие ограничения в этой статье были ограничениями конкретной библиотеки INI в Windows, а не самого формата INI. Другие, например, отдельные разрешения, можно легко обойти с помощью нескольких файлов. Официальная , модернизированная библиотека INI будет очень приветствоваться даже сегодня.

Шаги по использованию класса Ini

В определении пространства имен вашего проекта добавьте

Создайте такой INIFile

Используйте IniWriteValue , чтобы записать новое значение в определенный ключ в разделе, или используйте IniReadValue , чтобы прочитать значение ИЗ ключа в определенном разделе.

Я хочу прочитать полный INI-файл. Как сделать то же самое вместо раздела для чтения, ключ Это сработало для меня, а затем перестало работать с другой точки. До сих пор не знаю, что пошло по-другому под капотом Некоторое время я использовал этот подход, но улучшения безопасности, начиная с Win7, в значительной степени убили меня. Вы все еще можете использовать этот подход, но вы должны будете хранить .ini в ProgramData и ваше приложение будет читать / писать там. Не сохраняйте ini-файлы конфигурации приложения в ProgramData. Они не принадлежат ни к Реестру, ни к ProgramData. Файлы конфигурации должны находиться в папках LocalApplicationData.

Я нашел эту простую реализацию:

Хорошо работает для того, что мне нужно.

Вот как вы его используете:

+1 к смещению выше голоса против. На что вы действительно жалуетесь? Он сказал, что НАШЕЛ это. Вы отрицаете его за то, что он не нашел ни одного с универсальными аксессуарами и использованием построителей строк? @Tormod: Хотел бы я проголосовать против комментария. Это технический форум, когда мы голосуем за решения, а не за (очевидно положительные) намерения. Если решение, опубликованное самим Кнутом, имело недостатки, на это следовало бы указать. Неважно, было ли решение найдено или написано автором. Я думаю, вы растягиваете определение «недостаток». Если решение не подчеркивает вашу чувствительность, просто не голосуйте за. Я просто оставил записку, в которой говорилось, что уже отверг его голос против, чтобы остальные 7 парней, проголосовавших за мой комментарий, сами этого не сделали.

Код в ответе Джораджа вдохновляет.

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

Он использует некоторый LINQ, вложенный нечувствительный к регистру строковый словарь для хранения разделов, ключей и значений и чтения файла за один раз.

И спасибо, что не поместили туда catch (Exception ex) < throw ex; > Хороший! По крайней мере, требуются некоторые изменения, чтобы работать лучше. Строка 16: ini [""] = currentSection; Кому: // ini [""] = currentSection; Это должно быть удалено, так как каждый раз первый элемент [0] будет пустым сегментом из-за этой инициализации. Строка 36: currentSection [строка.Substring (0, idx)] = line.Substring (idx + 1); Кому: currentSection [line.Substring (0, idx) .Trim ()] = line.Substring (idx + 1) .Trim (); Пары и значения следует обрезать независимо, а не только в строке Обрезать. В файлах конфигурации, подобных INI, обычно добавляющие пары K-> V, как правило, выравнивают их внутри разделов. Спасибо! Мы были долгое время. Большое спасибо за ваши предложения. Все они имеют смысл и заслуживают хорошего обновления этого кода.

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

Просто добавлю, что вы получите ключи с Configuration["keyname"]

PeanutButter.INI - это упакованный в Nuget класс для манипулирования файлами INI. Он поддерживает чтение / запись, включая комментарии - ваши комментарии сохраняются при записи. Он достаточно популярен, протестирован и прост в использовании. Это также совершенно бесплатно и с открытым исходным кодом.

Отказ от ответственности: я являюсь автором PeanutButter.INI.

Не могли бы вы дать ссылку на документацию PeanutButter.INI?

Попробуйте этот метод:

Он создает словарь с ключом «-». Загрузить его можно так:

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

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

Чтобы сериализовать экземпляр Dictionary<string, Dictionary<string, string>> в файл .ini , я использую следующий код:

Он имеет различные очень удобные перегрузки для получения разделов / значений и очень легкий.

Если это не очевидно, глядя на верхний уровень библиотеки (для меня это было неочевидно!), Класс IniDcoument и другие находятся в ComLib.IO.

Вот моя собственная версия, использующая регулярные выражения. Этот код предполагает, что каждое имя раздела уникально - если, однако, это не так - имеет смысл заменить Dictionary на List. Эта функция поддерживает комментирование файлов .ini, начиная с ';' персонаж. Раздел начинается нормально [раздел], и пары ключ-значение также обычно идут «ключ = значение». То же предположение, что и для разделов - имя ключа уникально.

Для меня эта функция не работает: она забывает одну секцию из двух. Я пробовал с пустыми строками и без них перед [Разделом]. Вы можете скопировать пример вашего .ini, который не работает?

Вот мой класс, работает как шарм:

Использование очевидно, поскольку это статический класс, просто вызовите IniFileManager.IniWriteValue для чтения раздела или IniFileManager.IniReadValue для чтения раздела.

Этот подход уже был показан и объяснен в другом ответе. Что в вашем ответе не охвачено этим? Помните, что это работает, только если файл .ini сохранен в UNICODE (16-битный LE). Используйте Notepad ++ для преобразования текста в Unicode, потому что, если вы сохраните его в UTF-8, это не сработает. Допускается также ANSI, но вы не можете читать буквы с диакритическими знаками.

Вы должны читать и записывать данные из файлов xml, так как вы можете сохранить весь объект в xml, а также можете заполнить объект из сохраненного xml. Лучше легко манипулировать предметами.

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

Если вам нужен простой ридер без разделов и любых других dll, вот простое решение:

Тем не менее, существуют сторонние решения.

Хотя это правда, что XML-файлы конфигурации - это путь, это еще не ответ на вопрос или VLQ только для ссылок. Мне нравится старый метод (P / Inovke), и вы можете использовать юникод со старым методом, например: File.WriteAllBytes (path, new byte [] <0xFF, 0xFE>); Хороший пакет, но это может быть лучше. Он не может полностью проанализировать значение, которое содержит '=' Or '\ n'

Предисловие

Во-первых, прочитайте этот пост в блоге MSDN об ограничениях файлов INI . Если это соответствует вашим потребностям, читайте дальше.

Крошечный класс

Добавьте новый класс IniFile.cs для вашего проекта:

Как это использовать

Откройте файл INI одним из 3 следующих способов:

Вы можете написать некоторые значения, например, так:

Чтобы создать такой файл:

Чтобы прочитать значения из файла INI:

При желании вы можете установить [Section] :

Чтобы создать такой файл:

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

Вы можете удалить ключ следующим образом:

Вы также можете удалить целый раздел (включая все ключи) следующим образом:

Пожалуйста, не стесняйтесь комментировать любые улучшения!

Я немного опоздал, но это не хватает GetSections() метода. Возможно, более традиционным по умолчанию будут файлы .ini для каждого приложения (не для сборки) Path.GetFullPath(IniPath ?? Path.ChangeExtension(Application.ExecutablePath, ".ini")) . Старый и, насколько я уважаю Рэймонда Чена, многие ограничения в этой статье были ограничениями конкретной библиотеки INI в Windows, а не самого формата INI. Другие, такие как гранулярные разрешения, могут быть легко обойдены через несколько файлов. Официальная , модернизированы библиотека INI будет наиболее приветствовать, даже сегодня.

Шаги по использованию класса Ini

В своем определении пространства имен проекта добавьте

Создайте INIFile, как это

Используйте IniWriteValue для записи нового значения в определенный ключ в разделе или используйте IniReadValue для чтения значения ОТ ключа в определенном разделе.

Я хочу прочитать полный файл INI. Как сделать то же самое вместо чтения раздела, ключ это сработало для меня, а затем перестал работать с другой точки. Я использовал этот подход некоторое время, но улучшения безопасности, начиная с Win7, в значительной степени убили это для меня. Вы все еще можете использовать этот подход, но вы будете хранить INI-файл в ProgramData, и ваше приложение будет читать / писать там. Не сохраняйте ini-файлы конфигурации приложения в ProgramData. Они не принадлежат ни Реестру, ни Программным данным. Предполагается, что файлы конфигурации находятся в папках LocalApplicationData.

Я нашел эту простую реализацию:

Хорошо работает для того, что мне нужно.

Вот как вы используете это:

+1 к смещению выше понижающей. На что вы действительно жалуетесь? Он сказал, что НАЙДЕН. Вы не одобряете его за то, что он не нашел ни одного со стандартными средствами доступа и использованием stringbuilder? @Tormod: Жаль, что я не мог понизить комментарий. Это технический форум, когда мы голосуем за решения, а не заведомо позитивные намерения. Если бы решение, опубликованное самим Кнутом, имело недостатки, на это было бы и должно быть указано. Неважно, было ли решение найдено или написано постером. Я думаю, что вы растягиваете определение "недостаток". Если решение не подчеркивает вашу чувствительность, то просто не голосуйте. Я только что оставил записку о том, что я уже отрицал его отрицательное голосование, чтобы остальные 7 парней, которые проголосовали за мой комментарий, не делали этого сами.

Код в ответе Джориджа вдохновляет.

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

Он использует LINQ, словарь строк, нечувствительный к регистру, для хранения разделов, ключей и значений и чтения файла за один раз.

и спасибо за то, что не поместили это catch (Exception ex) < throw ex; >там Хорошо! По крайней мере, некоторые изменения необходимы, чтобы работать лучше. Строка 16: ini [""] = currentSection; To: // ini [""] = currentSection; Это должно быть удалено, поскольку каждый раз первый элемент [0] будет пустым сегментом из-за этой инициализации. Строка 36: currentSection [line.Substring (0, idx)] = line.Substring (idx + 1); To: currentSection [line.Substring (0, idx) .Trim ()] = line.Substring (idx + 1) .Trim (); Ключ и значения должны быть обрезаны независимо, а не только на линии Trim. В INI-подобных конфигурационных файлах, которые обычно добавляют пары K-> V, как правило, выравнивают эти равные внутри секций. Спасибо! Мы были долгое время. Большое спасибо за ваши предложения. Все они имеют смысл и заслуживают этого кода, чтобы иметь хорошее обновление.

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

Просто чтобы добавить, что вы получите ключи с Configuration["keyname"] Оставайтесь вне реестра! Данные конфигурации приложения не должны сохраняться в реестре.

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

Читайте также: