:: Главная :: Решения :: Статьи :: Проект "Русский help" :: Файловый архив :: Фотоальбом :: Ссылки ::
   Л и с о в о д ы   в с е х   с т р а н,  о б ъ е д и н я й т е с ь !!!  


Форумы  :: FAQ FoxPro

Как работать с ini-файлами
Дата: 01.05.05 11:17:58 ОтветитьЦитировать

Вопрос

Как работать (читать и записывать) с ini-файлами?

Ответ

ini-файл или файл с расширением из 3 букв "INI" (от слов initialization file - файл инициализации) - это обычный текстовый файл, который имеет специфическое содержание. Выглядит его содержимое примерно так:

// Комментарий
[Имя_раздела_1]
Имя_реквизита_1 = значение реквизита
Имя_реквизита_2 = значение реквизита

// Комментарий
[Имя_раздела_2]
Имя_реквизита_1 = значение реквизита
Имя_реквизита_2 = значение реквизита
Т.е. в квадратных скобках указывается имя раздела (другое название - "секция"), затем идет список реквизитов (другое название - "ключ") этого раздела и их значение. Количество разделов и количество реквизитов внутри раздела не ограничено.

Желательно давать имена разделам и реквизитам в одно слово из латинских букв без пробелов и спец.символов. Но это скорее перестраховка. Если для Вас удобнее воспринимать имя раздела или реквизита с пробелом (в два слова) - пишите с пробелом!

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

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

В принципе, можно прочитать такой файл из FoxPro функциями чтения текстовых файлов (FOPEN(), FREAD(), FileToStr() и т.п.) и сделать его разбор. "Но есть способ лучше" (с). Существуют специальные API-функции предназначенные для чтения и записи INI-файлов.

GetPrivateProfileString - считывает значение указанного реквизита из указанного раздела.
WritePrivateProfileString - записывает значение указанного реквизита в указанный раздел указанного ini-файла. Если указанного раздела или реквизита не существует, то он будет создан. Если указанного ini-файла не существует, то он также будет создан.

Выглядит это примерно так:

Запись значения в ini-файл

  
  Declare Integer WritePrivateProfileString In Win32API As WritePrivStr ;    
  	String cSection, ;	&& имя раздела  
  	String cKey, ;	&& имя реквизита  
  	String cValue, ;	&& значение реквизита  
  	String posfile	&& имя ini-файла с полным путем доступа  
    
  LOCAL lnError  
  lnError = WritePrivStr("TestSection", ;  
  			"TestKey", ;  
  			"TestValue", ;  
  			Fullpath("test.ini"))  
  IF lnError<>1  
 	* Запись в ini-файл не удалась. Произошла ошибка  
  ELSE  
 	* Смотрим, что получилось во вновь созданном файле  
  	MODIFY FILE test.ini  
  ENDIF

Чтение значения из ini-файл

  
  Declare Integer GetPrivateProfileString In Win32API  As GetPrivStr ;    
  	String cSection, ;		&& Имя раздела  
  	String cKey, ;		&& Имя реквизита  
  	String cDefault, ;		&& Значение по умолчанию, если нет указанного раздела или реквизита  
  	String @cBuffer, ;		&& Собственно считанное значение реквизита  
  	Integer nBufferSize, ;	&& Максимальное количество символов в считанном реквизите  
  	String posfile		&& имя ini-файла с полным путем доступа  
    
  LOCAL lcBuffer, lnBuffer  
  lcBuffer = SPACE(2000)  
    
  lnBuffer = GetPrivStr("TestSection", ;  
  			"TestKey", ;  
  			"Нет значения", ;  
  			@lcBuffer, ;  
  			LEN(m.lcBuffer), ;  
  			Fullpath("test.ini"))  
    
  IF m.lnBuffer = 0  
 	* Ничего не прочитали  
  ELSE  
 	* Прочитанное значение храниться в первых m.lnBuffer символах переменной m.lcBuffer  
  	?LEFT(m.lcBuffer,m.lnBuffer)  
 	* Общая длина переменной m.lcBuffer по прежнему 2000 символов,   
 	* но символ m.lnBuffer+1 имеет ASCII-код равный 0, а все прочие - пробелы  
  ENDIF

Удаление раздела или реквизита
Удаление - это запись не определенного значения

  
 * Удаление только одного реквизита TestKey в разделе TestSection  
  LOCAL lnError  
  lnError = WritePrivStr("TestSection", ;  
  			"TestKey", ;  
  			NULL, ;  
  			Fullpath("test.ini"))  
  IF lnError<>1  
 	* Запись в ini-файл не удалась. Произошла ошибка  
  ELSE  
 	* Смотрим, что получилось   
  	MODIFY FILE test.ini  
  ENDIF  
    
 * Удаление всего раздела TestSection со всеми реквизитами  
  LOCAL lnError  
  lnError = WritePrivStr("TestSection", ;  
  			NULL, ;  
  			NULL, ;  
  			Fullpath("test.ini"))  
  IF lnError<>1  
 	* Запись в ini-файл не удалась. Произошла ошибка  
  ELSE  
 	* Смотрим, что получилось   
  	MODIFY FILE test.ini  
  ENDIF

Определение структуры ini-файла

Если структура ini-файла, т.е. имена секций и ключей, заранее не известны, то получить структуру ini-файла можно также используя функцию GetPrivateProfileString указав вместо имени секции или ключа число 0.

В этом случае в качестве возвращаемого значения Вы получите либо список имен секций (если указать 0 первым параметром), либо список имен ключей указанной секции (если указать 0 вторым параметром). Имена будут разделены символом Chr(0)

  
 * Список секций ini-файла  
  LOCAL lcBuffer, lnBuffer  
  lcBuffer = SPACE(2000)  
    
  lnBuffer = GetPrivStr(0, ;  
  			0, ;  
  			"", ;  
  			@lcBuffer, ;  
  			LEN(m.lcBuffer), ;  
  			Fullpath("test.ini"))  
    
  IF m.lnBuffer > 0  
  	m.lcBuffer = CHR(0) + LEFT(m.lcBuffer,m.lnBuffer)  
  	LOCAL lnI, lnFromPos, lnToPos  
  	FOR m.lnI = 1 TO OCCURS(CHR(0),m.lcBuffer)-1  
  		lnFromPos = AT(CHR(0),m.lcBuffer,m.lnI)  
  		lnToPos = AT(CHR(0),m.lcBuffer,m.lnI+1)  
  		?SubStr(m.lcBuffer,m.lnFromPos+1,m.lnToPos-m.lnFromPos-1)  
  	ENDFOR  
  ENDIF  
    
 * Аналогично получаем список ключей секции TestSection   
  LOCAL lcBuffer, lnBuffer  
  lcBuffer = SPACE(2000)  
    
  lnBuffer = GetPrivStr("TestSection", ;  
  			0, ;  
  			"", ;  
  			@lcBuffer, ;  
  			LEN(m.lcBuffer), ;  
  			Fullpath("test.ini"))  
    
  IF m.lnBuffer > 0  
  	m.lcBuffer = CHR(0) + LEFT(m.lcBuffer,m.lnBuffer)  
  	LOCAL lnI, lnFromPos, lnToPos  
  	FOR m.lnI = 1 TO OCCURS(CHR(0),m.lcBuffer)-1  
  		lnFromPos = AT(CHR(0),m.lcBuffer,m.lnI)  
  		lnToPos = AT(CHR(0),m.lcBuffer,m.lnI+1)  
  		?SubStr(m.lcBuffer,m.lnFromPos+1,m.lnToPos-m.lnFromPos-1)  
  	ENDFOR  
  ENDIF

Разумеется, объявлять API-функции каждый раз перед записью или чтением значений нет необходимости. Достаточно объявить эти функции один раз в стартовом файле.

Также пример работы с INI-файлами можно посмотреть в классе, поставляемом вместе с FoxPro

MODIFY CLASS oldinireg OF HOME()+'FFC\registry.vcx'

Хотя в новейшей идеологии Microsoft предполагается, что вместо ini-файлов следует использовать запись/чтение в системный реестр Windows.

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



Исправлено: Владимир Максимов, 30.12.06 14:43
Ratings: 0 negative/1 positive


Тема Просмотров Написано Написано
  Program 4994 Владимир Максимов 01.03.05 21:02
  Как определить директорию, из которой запущена программа 8574 Владимир Максимов 22.03.05 09:41
  Как проверить факт существования переменной памяти, поля таблицы, метода формы 11271 Владимир Максимов 20.04.05 17:31
  Как работать с ini-файлами 14095 Владимир Максимов 01.05.05 11:17
  Символьные поля, переменные памяти и константы 8182 Владимир Максимов 25.09.05 12:31
  Как работать с путями доступа и именами файлов, содержащих пробелы 6108 Владимир Максимов 22.02.06 21:00
  Как вывести приложение на передний план 15839 Владимир Максимов 04.03.07 13:17
  Как получить разницу двух дат в формате: лет, месяцев, дней 9060 Владимир Максимов 25.02.08 17:32


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

On-line: 44 GM51 andrewk sphinx  and Guests: 41


© 2006 Fox Club 
Яндекс.Метрика