![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
THandle |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() Хранитель Клуба ![]() Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 65 Всего: 372 |
TIniFile. Работа с Ini-файлами в Delphi.
Что такое Ini файл? Ini файлы – это простые текстовые файлами с расширением .ini(в принципе можно и с любым другим). Обычно они хранятся в каталоге Windows. Ini файлы предназначены для хранения настроек программы. Ini файлы разделены на разделы, содержащие идентификаторы, которым, в свою очередь, можно присвоить значения. В общем виде структура Ini файла такова:
Выражение Идентификатор = Значение очень часто называют ключом. В Delphi работа с Ini файлами производится посредствам класса TIniFile, объявленного в юните IniFiles. TIniFile наследуется от класса TCustomIniFile, который в свою очередь, является прямым потомком TObject. Теперь рассмотрим свойства и методы класса TIniFile. Метод Create. Объявлен как:
Метод Create создает экземпляр класса TIniFile, который позволяет манипулировать Ini файлом, имя которого передаётся в параметре FileName. Если явно не указать, где именно нужно создать или найти Ini файл, Ваша программа будет искать его в каталоге Windows. Пример:
Свойство FileName. Объявлено как:
Это read only свойство хранит в себе имя Ini файла. Значение FileName присваивается только один раз во время работы с экземпляром класса TIniFile – в методе Create. Пример:
PS: Для работы данного примера так же следует подключить модуль Dialogs, так как в нем объявлена процедура ShowMessage. Методы WriteString, ReadString. Объявлены следующим образом:
Процедура WriteString записывает в раздел Section, в ключ с идентификатором Ident строку Value. Функция ReadString читает из раздела Section строку из ключа с идентификатором Ident. Если такой раздел или ключ не обнаружены в файле, то функция вернет заданный Вами параметр Default. Пример:
Методы WriteInteger, ReadInteger. Объявлены как:
Процедура WriteInteger записывает в ключ Ident находящийся в разделе Section целое число Value. Функция ReadInteger читает целое число из ключа с идентификатором Ident находящегося в разделе Section. PS: На самом деле в файл будут записаны не числа, а строки. То есть в WriteInteger в файл пишется не само Value, а преобразованное в строку число - IntToStr(Value). А в ReadInteger читается сначала строка, а в результате передаётся строка, преобразованная в число с помощью функции StrToInt. Пример: См. примеры к методам ReadString, WriteString. Методы WriteFloat, ReadFloat. Объявлены как:
Процедура WriteFloat записывает в ключ Ident находящийся в разделе Section натуральное число Value. Функция ReadFloat читает натуральное число из ключа с идентификатором Ident находящегося в разделе Section. PS: Аналогично Write(Read)Integer в файл пишется не само число, а строки. Но в ReadFloat, если не удастся сконвертировать строку в натуральное число, поднимется исключение типа EConvertError. Пример: См. примеры к методам ReadString, WriteString. Методы WriteBool, ReadBool. Объявлены как:
Процедура WriteBool записывает в ключ Ident находящийся в разделе Section натуральное число Value. Функция ReadBool читает натуральное число из ключа с идентификатором Ident находящегося в разделе Section. PS: Аналогично Write(Read)Integer(Float) в файл пишется не само число, а строки. Точнее либо '1', либо '0'. Пример: См. примеры к методам ReadString, WriteString. Методы WriteDate, ReadDate. Объявлены как:
WriteDate записывает в раздел с именем Section ключ с идентификатором Name и значением Value. Функция ReadDate читает значение ключа с идентификатором Name, находящегося в разделе Section. Если ключ не найден, то результатом работы функции будет параметр Default. Если в ключе находится значение отличное от типа TDateTime, будет поднято исключение EConvertError. Так же как и во всех предыдущих методах чтения/записи, в Ini файле, после записи в него даты, будут находится строки, а при чтении будет выполнено преобразование в TDateTime. Пример:
Методы WriteTime, ReadTime. Объявлены как:
WriteTime, ReadTime являются полными копиями WriteDate, ReadDate, но пишут не дату, а время. Пример: См. Пример к методам WriteDate, ReadDate. Методы WriteDateTime, ReadDateTime. Объявлены как:
Эти два метода класса TIniFile записывают в файл дату и время и соответственно читают их. В остальном они схожи с WriteDate и ReadDate. Пример: См. Пример к методам WriteDate, ReadDate. Методы WriteBinaryStream, ReadBinaryStream. Объявлены как:
Процедура WriteBinaryStream записывает в ключ с идентификатором Name раздела Section данные из потока Value. Во время работы процедуры данные из потока преобразуются в шестнадцатеричную строку, и уже после этого записываются в файл. Функция ReadBinaryStream читает в поток Value значение ключа с идентификатором Name, находящегося в разделе Section. Результатом является размер потока. Пример: Положите на форму компонент TMemo и две кнопки(TButton).
Метод ReadSection. Объявлен как:
Читает все идентификаторы ключей в разделе Section и заносит их в Strings. Пример: Положите на форму компонент TMemo.
Результат: В Memo1 отобразится следующий список:
Метод ReadSections. Объявлен как:
Читает имена всех разделов в Ini файле и заносит их в Strings. Пример: Положите на форму компонент TMemo.
Результат: В Memo1 отобразится следующий список:
Метод ReadSectionValues. Объявлен как:
Читает все ключи (идентификатор=значние) в разделе Section и заносит их в Strings. Пример: Положите на форму компонент TMemo.
Результат: В Memo1 отобразится следующий список:
Метод DeleteKey. Объявлен как:
Метод DeleteKey удаляет из Ini файла ключ в разделе Section с идентификатором Ident. Пример:
Метод EraseSection. Объявлен как:
Метод EraseSection удаляет целый раздел из Ini файла. Параметр Section – имя раздела, который надо удалить. Пример:
Метод ValueExists. Объявлен в виде следующей функции:
Функция проверяет наличие ключа с идентификатором Ident в разделе Section Ini файла. Если данный ключ в разделе присутствует - функция вернет true, иначе false. Пример:
Метод SectionExists. Объявлен в виде функции:
Функция проверяет наличие раздела Section в Ini файле. Если данный раздел в файле присутствует - функция вернет true, иначе false. Пример:
Это сообщение отредактировал(а) THandle - 17.7.2008, 17:02 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SneG0K |
|
|||
![]() Max Mara ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1887 Регистрация: 1.12.2007 Где: Wis Dells Репутация: 1 Всего: 54 |
Молоток=)))
![]() |
|||
|
||||
Ofer |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 293 Регистрация: 15.10.2006 Где: КривбаСС Репутация: 1 Всего: 5 |
А для работы с реестром статейка будет? ))
|
|||
|
||||
THandle |
|
|||
![]() Хранитель Клуба ![]() Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 65 Всего: 372 |
Ofer, да, наверное.
![]() ЗЫ: Если найдете ошибки, опечатки, неточности и тд., пожалуйста, напишите об этом в PM, исправлю. ![]() |
|||
|
||||
Magik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 54 Регистрация: 6.12.2007 Репутация: нет Всего: 2 |
Есть способ хранить настройки и данные в файле *.dat. Такой способ лучше тем, что прочитать его содержимое (или изменить) - дело бесполезное.
|
|||
|
||||
ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: нет Всего: 17 |
А у меня и из папки программы (а не Windows) нормально открывается ini-файл. Вот так открываю файл, с тем же именем, что и exe-шник, но расширением ini:
-------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Там же написано ОБЫЧНО. Это не значит, что обязательно, это ближе к слову ЧАСТО или ПРИНЯТО. Можно куда угодно его сувать. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Это точно! Есть у меня знакомый, так он ini с настройками в ресурсы dll пихает (ну у него там в этой dll картинки, формы. Он туда и настройки сует)
![]() -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: нет Всего: 17 |
Я имел в виду, что если не указывать путь, а только имя файла, то он будет искаться при открытии в папке программы, а не в папке Windows -------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
THandle |
|
|||
![]() Хранитель Клуба ![]() Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 65 Всего: 372 |
ksili, хорошо, давайте напишем такой вот примерчик:
На формочку кидаем две кнопочки и в ОнКлик их пишем следущее:
Сохраняем весь "проект" в какую - нибудь папку. Теперь запускаем эту программу. Жмем первую кнопку. В проводнике открываем каталог Windows. Вот он наш файл - Ini.ini. Создан именно в каталоге Windows, а не нашей программы. Теперь перемещаем этот файл в каталог нашей программы. Именно перемещаем, а не копируем. Программа наша всё это время работает. Теперь жмем вторую кнопку. Результат: файл не найден, хотя находится в каталоге нашей программы, ключ невозможно прочитать, и поэтому в сообщении показывается не записанное нами в значение, а параметр Default равный в данном случае 'Not found'. Вывод: если явно не указать программе где искать Ini файл, она будет искать его в каталоге Windows. |
|||
|
||||
ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: нет Всего: 17 |
а-а-а, я понял в чём прикол: в Application->ExeName из моего примера входит полный путь до exe-шника
-------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
THandle |
|
|||
![]() Хранитель Клуба ![]() Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 65 Всего: 372 |
||||
|
||||
lukas |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 771 Регистрация: 23.2.2007 Репутация: 3 Всего: 15 |
Нужно еще заметить, что ИНИ-файл в win98 не может превышать размер 64 кб, и естественно если мы не указываем полный путь, то ини-файл сохраняется в папке windows, думаю это не очень красиво...
![]() ![]() -------------------- http://code.google.com/p/orionphp/ - opensource скриптовой язык Orion (аналог PHP) для freepascal/delphi. |
|||
|
||||
THandle |
|
||||
![]() Хранитель Клуба ![]() Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 65 Всего: 372 |
Думал над этим, но как мне кажется Win98 начинающие программисты сейчас не используют.
Это уже описано ![]() Про него то я и напишу в следующей после реестра статье. Это сообщение отредактировал(а) THandle - 26.2.2008, 18:00 |
||||
|
|||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: нет Всего: 162 |
Зашёл поглядеть, толковая статья вышла
![]() |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 31 Всего: 88 |
Добавлено через 12 минут и 28 секунд логика поиска описана в хелпе к функции WritePrivateProfileString -------------------- Обижено школьников: 8 |
|||
|
||||
aktuba |
|
|||
![]() Смышленный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1915 Регистрация: 24.4.2006 Где: Планета Земля Репутация: 16 Всего: 38 |
С чего это ты решил? Смотря как хранится в самом файле, а в .dat можно хранить как угодно, хоть тот же .ini... -------------------- ![]() |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Все зависит от желаемого функционала. Что от чего должно зависеть и сохраняться. По современным требованиям это вообще должен быть либо реестр либо папка Aplication Data текущего юзера. В Своем каталоге обычно хранят настройки простые программы, для которых весь дом ограничивается своей папкой. Если приложение регистрируют COM/ActiveX, то оно в любом случае зависимо от текущей ОС. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
bems |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 31 Всего: 88 |
-------------------- Обижено школьников: 8 |
||||
|
|||||
Lexicss |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 197 Регистрация: 16.8.2006 Где: Беларусь, Минск Репутация: нет Всего: 1 |
Эх, вот бы мне эту статейку полтора года назад встретить. - когда нужно было срочно разбираться с инишками, пришлось тратить время и экспериментить. А наткнулся бы сразу на эту статеку - 5 минут и хватило б.
![]() --------------------
Бери от жизни всё. |
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
все расжевано так, что даже самые одаренные поймут. хотя в справке и так все нормально и подробно написано, за исключением примеров
-------------------- There are always someone smarter than you... |
|||
|
||||
THandle |
|
|||
![]() Хранитель Клуба ![]() Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 65 Всего: 372 |
К сожалению все эти "самые одаренные" даже не слышали о справке, а если и слышали, то не юзают, так как на английском, и якобы не понятно ![]() |
|||
|
||||
Saygak |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 2.5.2007 Репутация: 1 Всего: 1 |
В методе ReadSectionValues в примере нужно заменить
на
|
||||
|
|||||
THandle |
|
|||
![]() Хранитель Клуба ![]() Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 65 Всего: 372 |
Интересно как такой пример вообще прошел в статью)) вроде бы все проверял...
Изменено. Saygak, +1 в репу. |
|||
|
||||
skeef |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 3.3.2010 Репутация: нет Всего: нет |
Перерыл пол-инета нигде не могу найти ответ на простейший вопрос:
формат комментариев в ini файлах Delphi. Как правильно? |
|||
|
||||
Heriz |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 21.3.2010 Репутация: нет Всего: нет |
Вопрос: Как проверить параметр в ини файле и занести в программу?Используется параметр MainMenu1.Images:=imagesList1; и есть второй Imagelist2
![]() |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
через ";" например ;comment Параметр в INI можно только прочитать. Если его нет, то будет подставлено значение по умолчанию. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
RomanEEP |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 424 Регистрация: 18.5.2006 Где: Коломна Репутация: 5 Всего: 8 |
Для проверки наличия параметра есть функция function ValueExists(const Section, Ident: string): Boolean; При работе с Ini файлами в Delphi 2010 столкнулся с жесткими косяками в TMemIniFile: 1) Access Violation при открытии пустых файлов в строке 727 Inifiles.pas из-за кода SetLength(Buffer, Size); Stream.Read(Buffer[0], Size); проверить size на 0 нынче не модно... 2)Для быстрого поиска подстроки используются хешированные стринг-листы в которых обновление хеша сделано крайне неграмотно: при любом изменении стринг листа хеш перестраивается заново! то есть если в секции есть 100 строк, то добавление 101 строки вызовет пересчет хеш функции для всех 100 строк. Благодаря этому файл в пару сотен строк пишется секунд 5! Использовать ини файлы ушло всякое желание когда наткнулся на юнит NativeXml - который стал бесплатен. Имеет интуитивно понятный и небольшой набор функции, который быстро заменит сохранение в ини-файлы + большая гибкость xml + высокая скорость работы. Для примера: время чтения с диска и распарсивания файла размеров в 500Kb (около 50000 значений) занимает 0,2с на 1800MHz. За собой тянет один единственный модуль размеров в 6000 строк |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
А если воспользоваться старым добрым TIniFile ? Дело в том, что Ini файлы предназначены для хранения небольших объемов файлов. Тут нет оптимизации по скорости. Не подразумевается частое обращение. Простой способ сохранить уникальные данные. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
RomanEEP |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 424 Регистрация: 18.5.2006 Где: Коломна Репутация: 5 Всего: 8 |
Согласен? но TMemIniFiles создавался как оптимизированый вариант TIniFile и надо же было к 2010 году ембаркадеровцам соптимизировать так что сделали раз в 10 медленней оригинала!
ЗЫ: Еще в по поводу методов WriteFloat, ReadFloat во первых они записывают не натуральные, а действительные числа)))) а во вторых есть неприятная особенность, что если в системе сменится DecimalSeparator или IniFile будет читаться с другого компа, то эти значения просто напросту не считаются! Приходится придумывать велосипеды вроде смены разделителя при чтении из инишки или переопределения метода ReadFloat, WriteFloat |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
На самом деле косяки есть. Писалось все это (VCL) различными программистами. Некоторый код написан отлично, а второстепенные вещи отдавались на откуп программистам с меньшей квалификацией. Можешь лучше, перепиши и представь им свой код. Они не против замены неудачных частей. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
RomanEEP |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 424 Регистрация: 18.5.2006 Где: Коломна Репутация: 5 Всего: 8 |
Целью моего поста было сказать, что с моей точки зрения Ini файлы несколько устарели и не очень удобны и есть отличный вариант для их замены - http://www.simdesign.nl/xml.html Написан отлично и не вижу смысла его переписывать!
|
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Ну если говорить о заменах, то в новых версиях делфи есть встроенная поддержка JSON. TJSONObject модуль DBXJSON. Он удобен для хранения состояния объектов. Более специализированный и подходящий вариант чем XML. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
||||
|
||||
kandiral |
|
|||
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 17.9.2015 Репутация: нет Всего: 2 |
Я сделал более простой вариант работы с ini файлами, где каждый параметр является отдельным объектом и с ним можно работать из кода по имени.
https://kandiral.ru/delphi/primer_ispolzova...riniconfig.html В моём случае также используется TIniFile, но косвенно(не напрямую) |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |