Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.05.20;
Скачать: CL | DM;

Вниз

Чтение многострочного ключа ini-файла   Найти похожие ветки 

 
Kostafey ©   (2007-04-27 17:25) [0]

Подкажите пожалуйста существует ли возможность чтения/записи многстрочных ключей ini-файлов ?
Т.е. что бы вместо

[section1]
key1="жили у бабуси 2 веселых гуся"
key2=...

можно было писать:

[section1]
key="жили у
    бабуси 2
    веселых
    гуся"
key2=...


 
tesseract ©   (2007-04-27 17:27) [1]

существует, измени ко конечного автомата у TIniFile


 
clickmaker ©   (2007-04-27 17:38) [2]

Stream := TStringStream.Create(MultiLineText);
IniFile.WriteBinaryStream("Section1", "key", Stream);


 
Loginov Dmitry ©   (2007-04-27 17:47) [3]

Если так нужно, чтобы в инишке хранился многострочный текст, то можно записать его в виде одной строки:
Ini.WriteString("section1", "key1",
 StringReplace(S, sLineBreak, "\n", [rfReplaceAll]));

Читать так:
S := StringReplace(Ini.ReadString("section1", "key1", ""), "\n", sLineBreak, [rfReplaceAll]);

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


 
Kostafey ©   (2007-04-27 18:19) [4]

> существует, измени ко конечного автомата у TIniFile

А как?


> Stream := TStringStream.Create(MultiLineText);

К сожалению не приходилось еще иметь дело с потоками.
Как же правильно считать данные?

 IniFile.ReadBinaryStream("Section1", "key", Stream);
 Stream.Position:=0;
 Showmessage(Stream.ReadString(100));

Выдает набор символов


> [3] Loginov Dmitry ©   (27.04.07 17:47)

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

> ини ограничена и не может быть больше 2048 символов.

В справке упоминаний об этом я не видел, похоже действительно
нужно работать с TMemIniFile. Спасибо.


 
clickmaker ©   (2007-04-27 18:20) [5]


> IniFile.ReadBinaryStream("Section1", "key", Stream);

ShowMessage(Stream.DataString);


 
Kostafey ©   (2007-04-27 18:29) [6]

> [5] clickmaker ©   (27.04.07 18:20)

Пробую для однострочного варианта:

var
 ttstr:string;
...
Stream := TStringStream.Create(ttstr);
IniFile.ReadBinaryStream("Section1", "key", Stream);
ShowMessage(Stream.DataString);

Выдает:
юp-
p-
p-
p-
p-
p-
p-
p-
p-
p-


 
clickmaker ©   (2007-04-27 18:42) [7]

при чтении
Stream := TStringStream.Create("");

и как записываешь?


 
Kostafey ©   (2007-04-27 18:50) [8]

> и как записываешь?

А пока пытаюсь просто прочесть:

 Stream := TStringStream.Create("");
 IniFile.ReadBinaryStream("Query0", "SQL", Stream);
 ShowMessage(Stream.DataString);

Реальное содержание ini-файла:

[Query0]
sql="Select * from Dogovor, Subject where Dogovor.D_S_id = Subject.S_id"

И выдает [6]

Если просто

ShowMessage(IniFile.ReadString("Query0", "SQL", ""));

то все OK


 
Kostafey ©   (2007-04-27 20:22) [9]

Вот так да.
http://kladovka.net.ru/delphibase/?action=viewfunc&topic=fileini&id=10302
не работает.
Строки загружаются пустые.


 
clickmaker ©   (2007-04-28 15:14) [10]


> [8] Kostafey ©   (27.04.07 18:50)

ну ё... чтобы прочесть как двоичный поток, данные и записаны должны быть как двоичный поток
Ты уж определись


 
Kostafey ©   (2007-04-28 16:45) [11]

> ну ё... чтобы прочесть как двоичный поток, данные и записаны
> должны быть как двоичный поток
> Ты уж определись

Ну да, по поводу [8] Kostafey © я молчу - глупость.

А если даже и запись потока делать - тоже самое получается.
В http://kladovka.net.ru/delphibase/?action=viewfunc&topic=fileini&id=10302
как раз такой пример приводится. И он не работает.

Вообще, идея несколько в другом. Я хотел чтобы ini-файл можно было бы читать и
вручную (по F4). Если файл, становится нечитаемым в ручном режиме,
то разницы нет, можно и как [3] Loginov Dmitry ©   (27.04.07 17:47)
предложил сделать.

Или уж вообще тогда читать файл не как ini, а в двоичном режиме,
если, конечно нет лучших вариантов?


 
clickmaker ©   (2007-04-28 17:39) [12]


> А если даже и запись потока делать - тоже самое получается.


вот так делаешь?

procedure TForm1.Button1Click(Sender: TObject);
var
 IniFile: TIniFile;
 Stream: TStringStream;
begin
 IniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, ".ini"));
 Stream := TStringStream.Create(Memo1.Text);
 try
   IniFile.WriteBinaryStream("Section1", "key", Stream);
 finally
   IniFile.Free;
   Stream.Free;
 end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 IniFile: TIniFile;
 Stream: TStringStream;
begin
 IniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, ".ini"));
 Stream := TStringStream.Create("");
 try
   IniFile.ReadBinaryStream("Section1", "key", Stream);
   Memo2.Text := Stream.DataString;
 finally
   IniFile.Free;
   Stream.Free;
 end;
end;


 
Kostafey ©   (2007-04-28 20:16) [13]

> [12] clickmaker ©   (28.04.07 17:39)

Пример [12] работает.
Теперь понял в чем ошибка.
Если вместо TIniFile использовать TMemIniFile, то при записи потока
(неважно TStringStream или TMemoryStream) ничего записано не будет.
Вообще.

При использовании TIniFile - для записи, TMemIniFile - для чтения все
работает хорошо.
Будет ли существовать в таком случае при записи с использованием TIniFile
ограничение в 2048 символов ?


 
Ketmar ©   (2007-04-28 20:21) [14]

берём Lua. используем. получаем помимо читабельных инишек ещё и скриптовый язык задаром. %-)


 
Kostafey ©   (2007-04-28 20:27) [15]

> [14] Ketmar ©   (28.04.07 20:21)

Lua, lua... что-то знакомое.
Не приходилось пользоваться. Не подскажете где документацию по нему поискать ?

З.Ы. Google, Yandex уже шуршат...


 
Ketmar ©   (2007-04-28 20:36) [16]

http://www.lua.org/

правда, оно щаз на maintenance. в понедельник поднимется. там и исходники, и доки, и ссылки, и вообще много вкусного. только вменяемого модуля для Delphi/FPC нет. у меня свой. тоже кривой. %-)


 
Kostafey ©   (2007-04-28 20:55) [17]

Жесть, это же целый скриптовый язык.

Несомненно, он применим сам по себе, но что ж такого особенного
в нем, что позволяет использовать его для хранения небольшого количества информации?

Если использовать средства Lua, то это ж надо искать соотвествующие примеры
кода/компоненты для Delphi.
А если их не использовать, то игра и свеч не стоит.

а к нему еще и интерпритатор устанавливать надо


 
Loginov Dmitry ©   (2007-04-28 21:34) [18]

> Будет ли существовать в таком случае при записи с использованием
> TIniFile
> ограничение в 2048 символов ?


Вообще нет ограничения на длину строки при записи. Такое ограничение действует только при чтении.


 
Ketmar ©   (2007-04-28 22:11) [19]

> Kostafey © (28.04.07 20:55) [17]
> Жесть, это же целый скриптовый язык.

угу. и очень изящный, к тому же. и очень быстрый.
у меня на pIII/600 конфиги объёмом в 200-300 кил читает практически мгновенно. %-)

> Несомненно, он применим сам по себе, но что ж такого особенного
> в нем, что позволяет использовать его для хранения небольшого
> количества информации?

а ничего особенного. просто красиво и удобно. и на халяву встроеный язык получаешь. %-)
опять же -- инкрементальный GC. халявная структуризация конфигов (а реализация ассоциативных массивов в Lua ОЧЕНЬ шустрая).

я за своим более-менее большим софтом заметил такую тенденцию: со временем всё больше функционала мигрирует из Delphi/C в Lua. на Lua удобно "прототипировать" новый код -- быстро отлаживается (есть отличная штука -- ldb: отладчик Lua на самой Lua, похож на gdb; монтируем в программу консоль (можно и по telnet"у общаться тогда %-) -- и отладка в руках; без перекомпиляции). а когда отлажено -- как-то уже и лениво переводить на "родной" язык. так и остаётся на Lua.

> Если использовать средства Lua, то это ж надо искать соотвествующие
> примеры кода/компоненты для Delphi.
> А если их не использовать, то игра и свеч не стоит.

нифига. там настолько простое и внятное API, что достаточно почитать мануал и примеры на C. а модулем для Delphi/FPC я могу поделиться, нет проблем. и простыми примерами тоже. и примерами создания библиотек расширения в виде .DLL или сразу в своём коде.

> а к нему еще и интерпритатор устанавливать надо
одна DLL, размером менее 200 килобайт. в принципе -- можно извратиться и собрать на BCC как набор .obj, после чего и DLL не нужна будет.


 
Ketmar ©   (2007-04-28 22:12) [20]

вдогон: вообще, Lua родилась именно как язык для конфигов. а потом уже "повзрослела". %-)


 
Kostafey ©   (2007-04-29 00:05) [21]

> Вообще нет ограничения на длину строки при записи. Такое
> ограничение действует только при чтении.

Спасибо, а  что же действительно запись в поток TMemIniFile невозможна ?


> на pIII/600 конфиги объёмом в 200-300 кил читает практически
> мгновенно

Впечатляет !


> я за своим более-менее большим софтом...

Функционал в скрипте? Гм. Вы меня заинтересовали.


> нифига. там настолько простое и внятное API, что достаточно
> почитать мануал и примеры на C. а модулем для Delphi/FPC
> я могу поделиться, нет проблем. и простыми примерами тоже.
> и примерами создания библиотек расширения в виде .DLL или
> сразу в своём коде.

Вы говорите о FPC, имеется в виду Lazarus?
Что касается модуля... модуля от Ketmar"a??? Я ж в нем буду до 2-го пришествия разбираться.
Впрочем, если не сложно, отправьте пожалуйста какие-нибудь простые примеры записи/чтения
конфигоподобных файлов Lua.

С dll я работал. Как на СPP, так и Delphi, так что все равно для dll или exe код.
А вот с obj иметь дело не доводилось, так что разберусь я в этом навряд ли.

<offtop>
помниться в старой инфе у вас было сказано что-то вроде:
"не люблю, когда говорят спасибо"
</offtop>

P.S. Документации немного набрал. Буду разбираться.


 
Ketmar ©   (2007-04-29 00:24) [22]

> Kostafey © (29.04.07 00:05) [21]
> Функционал в скрипте? Гм. Вы меня заинтересовали.

а отчего бы и да? %-) удобно, гибко настраивается и вообще здорово.

> Вы говорите о FPC, имеется в виду Lazarus?
нет. имея в виду FPC. ибо модуль -- он просто wraper для DLL/so. я ведь и в консольном/WinAPI/Linux libc софте использую Lua. %-)

собственно, я вообще сейчас достаточно много мелкого утиля пишу на "чистом" Lua (с допбиблиотеками %-). имея биндинги к сокетам, GTK и прочим вкусностям можно не заморачиваться всякими сями и паскалями. %-)

более того, для Lua есть LuaJIT. который добавляет к .DLL где-то 50-60 кил, но скорость увеличивает ощутимо. и не накладывает никаких ограничений на язык. только не знаю, портанул ли его SuperMike под 5.1.2.

> Что касается модуля... модуля от Ketmar"a??? Я ж в нем буду
> до 2-го пришествия разбираться.

неа. это straightforward трансляция сишных хидеров.

> Впрочем, если не сложно, отправьте пожалуйста какие-нибудь
> простые примеры записи/чтения
> конфигоподобных файлов Lua.

надо тогда напомнить мне завтра в аську -- 43443522. накропаю.

на самом деле если учитывать, что у меня обычно (как я и говорил) масса функционала непосредственно на Lua сделана, то многие конфиги в самих скриптах и используются, до "родного" кода не добираясь. %-)

но я поищу -- была где-то софтинка, которая читает "структурированые" конфиги и потом их можно получиать при помощи функций типа CfgGetIntKey("server.proxy.port");.

хотя потом я перешёл к варианту, который разбирает конфиг сам (Lua-скрипт) и настраивает софтину при помощи всяких штук типа SetProxyPort(8080); из самого скрипта.

а потом и вовсе к server.proxy.port = 8080;, что автоматически вызывает SetProxyPort(8080) в "родном" коде. и, соотвтетсвенно, print(server.proxy.port); вызывает GetProxyPort();. и опять получается конфиг в виде plain text. %-)

> С dll я работал. Как на СPP, так и Delphi, так что все равно
> для dll или exe код.

я имел в виду пример использования API и оформления DLL так, чтобы Lua его поняла как внешний модуль и подключила при помощи require "module". оно с первого раза не совсем "прозрачно".

> А вот с obj иметь дело не доводилось, так что разберусь
> я в этом навряд ли.

Lua без напильника собирается при помощи BCC. в DLL. %-) а отсюда уже не так далеко до просто .obj и {$LINK xxx.obj}. только пару стандартных Lua-библиотек придётся написать на Delphi, чтобы не тянуть с собой C runtime.

"не люблю, когда говорят спасибо"
само слово. от благодарностей в виде tnx и спиртосодержащих не отказываюсь. %-)

P.S. Документации немного набрал. Буду разбираться.
если что -- можно стукать в асю. при нужде попытаюсь пинком задать верное направление. %-)


 
Kostafey ©   (2007-04-29 01:05) [23]

> нет. имея в виду FPC. ибо модуль -- он просто wraper для
> DLL/so. я ведь и в консольном/WinAPI/Linux libc софте использую
> Lua. %-)

понял... с 4-го прочтения...


> собственно, я вообще сейчас достаточно много мелкого утиля
> пишу на "чистом" Lua (с допбиблиотеками %-). имея биндинги
> к сокетам, GTK и прочим вкусностям можно не заморачиваться
> всякими сями и паскалями. %-)

Тоже понял. Пока мне это ни к чему.


> straightforward трансляция сишных хидеров

Ну с таким же успехлм мне можно было написать
Заджикали заджикали Все тенали бороговы (с)Льюис Кэрролл
не понял ни слова. :)


> надо тогда напомнить мне завтра в аську -- 43443522. накропаю.

OK


> но я поищу -- была где-то софтинка, которая читает "структурированые" конфиги и потом их можно получиать при помощи функций типа > CfgGetIntKey("server.proxy.port");.

Было бы здорово. Но это ж нужно незнамо как настраивать пользовательскую машину при установке.


> хотя потом я перешёл к варианту, который разбирает конфиг
> сам (Lua-скрипт) и настраивает софтину при помощи всяких
> штук типа SetProxyPort(8080); из самого скрипта.
>
> а потом и вовсе к server.proxy.port = 8080;, что автоматически
> вызывает SetProxyPort(8080) в "родном" коде. и, соотвтетсвенно,
> print(server.proxy.port); вызывает GetProxyPort();. и опять
> получается конфиг в виде plain text. %-)

Ох да. я даже в Delphi не знаю как это делается.


> я имел в виду пример использования API и оформления DLL
> так, чтобы Lua его поняла как внешний модуль и подключила
> при помощи require "module". оно с первого раза не совсем
> "прозрачно".

Как впрочем и со второго :)


> само слово. от благодарностей в виде tnx и спиртосодержащих
> не отказываюсь. %-)

Первое не знаю что такое, а что касается вторго, то все зависит в каком городе
вы находитесь/будете находится :))).


> при нужде попытаюсь пинком задать верное направление. %-)

Тоже правильно :)


 
Ketmar ©   (2007-04-29 01:18) [24]

> Kostafey © (29.04.07 01:05) [23]
> не понял ни слова. :)
просто перевод заголовочного файла с импортами из DLL. с сей на паскаль.

> Было бы здорово. Но это ж нужно незнамо как настраивать
> пользовательскую машину при установке.

положить lua5.dll в тот же каталог, где твоя софтина лежит. %-)

а дефолтные конфиги должны идти с софтиной. или она должна уметь их делать сама.

> Ох да. я даже в Delphi не знаю как это делается.
классами и свойствами. %-)

> Первое не знаю что такое
tnx==thanx==thank you.


 
Kostafey ©   (2007-04-29 01:33) [25]

> положить lua5.dll в тот же каталог, где твоя софтина лежит.
> %-)

Да я про настройку прокси сервера. Хорошо бы без этого.
Вдруг у них уже сеть есть.

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

> а дефолтные конфиги должны идти с софтиной. или она должна
> уметь их делать сама.

это-то само собой


> классами и свойствами. %-)

А, черный юмор ;]


 
Ketmar ©   (2007-04-29 02:20) [26]

да я пример с прокси так привёл, "с потолка". с проксей -- это вообще куски из in-house проекта. %-)


 
Kostafey ©   (2007-04-30 21:04) [27]

Ситуация такая.

Компиляция.

При обработке строк .bat - файла, например:
cl /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DLUA_BUILD_AS_DLL l*.c
выдает: Программа не умещается в памяти.

Ну да ладно, скомпилоровалось в Visual Studio 2005.
Скомпилировался файл lua5.1.dll, а lua51U.pas просит lua51.dll.
ну да ладно lua51.dll есть в любой готовой компиляции.
Запускаем приложение на Delphi - просит msvcr80d.dll.
Ищем msvcr80d.dll - их куча.
Подходящая в C:\Program Files\Microsoft Visual Studio 8\VC\ce\Dll\x86\.
Запускаем - просит CORE.dll. Находим CORE.dll, запускаем - все рушится (не найдена такая-то строка в CORE.dll).

Ладно, есть готовые компиляции всей библиотеки. Например, lua5_1_2_Win32_dll7_lib.zip.
Берем от туда lua5.1.dll и lua51.dll - все, приложение работает.
Вопрос: на другом PC понадобятся какие-либо еще библиотеки помимо этих двух ?

Что до самого Lua.
Я хотел бы хранить там информацию типа:

#Sql.lua

--Количество запросов
Count=1

--Список запросов
Query_1 = {}
Query_1.Name="Запрос №1"
Query_1.SQL=[[
Select *
From Dogovor, Subject
Where ?Param_1 and ?Param_2
 and Dogovor.D_S_id = Subject.S_id"
]]
--
Query_1.Params={}
Query_1.Params.Count=2
Query_1.Params.Param_1={}
Query_1.Params.Param_1.Name="Data"
Query_1.Params.Param_1.FieldName="Dogovor.Data"
Query_1.Params.Param_1.Operation="between"
Query_1.Params.Param_1.Operand1=""
Query_1.Params.Param_1.Operand2=""
--
Query_1.Params.Param_2={}
Query_1.Params.Param_2.Name="Familiya"
Query_1.Params.Param_2.FieldName="Subject.Familiya"
Query_1.Params.Param_2.Operation="="
Query_1.Params.Param_2.Operand1=""

Получается по-другому ее не записать (структур я в языке не нашел) ?

Обработка команд
Вот что непонятно:

procedure TForm1.Button4Click(Sender: TObject);
var LuaS: PLuaState;
begin
 LuaS := lua_open();
 showmessage(inttostr(luaL_dostring(LuaS, "print(print("Hellow World"))")));
end;

Выводит в диалоге "2".
В модуле lua51U.pas: LUA_ERRRUN    = 2;
Как мне кажется вернуть он наверное должен 0, и на консоль вывести Hellow World ?

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

Если с переменными все OK:

LuaS := lua_open();
luaL_dofile(LuaS, ExtractFilePath(Application.ExeName) + "\sql.lua");
lua_getglobal(LuaS, "Count");
ShowMessage(lua_tostring(LuaS, 1));

То как привильно считывать таблицы я так и не понял.

lua_gettable на сколько я понял передает таблицу в стек. Но какую и как потом из нее извлекать значения ?


 
Kostafey ©   (2007-04-30 21:11) [28]

> showmessage(inttostr(luaL_dostring(LuaS, "print(print("Hellow > World"))")));

showmessage(inttostr(luaL_dostring(LuaS, "print("Hellow World")")));


 
Ketmar ©   (2007-04-30 21:59) [29]

барин, не надо извращений. %-)

>Скомпилировался файл lua5.1.dll, а lua51U.pas просит lua51.dll.
для кого в .pas константа сделана с именем библиотеки?

>Вопрос: на другом PC понадобятся какие-либо еще библиотеки помимо этих двух ?
собери нормально. или скачай вменяемую. нужна только одна -- lua*.dll.

>Получается по-другому ее не записать (структур я в языке не нашел) ?
таблицы -- это и массивы, и структуры, и классы, и словари и ещё много чего. да. %-)

а зачем тебе Params.Count? массивы -- они и числовые индексы принимают. если начинать с 1, то длина массива -- #<var>. и никаких ручных _1, _2, ...

>Выводит в диалоге "2".
и что неясно? медитируем:
print(print("zzz"));
кто тебе наврал, что print() возвращает какой-то результат? напиши так: WriteLn(WriteLn("text"));. не удивительная ли конструкция? %-)

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

да. для чего делается функция-"обёртка". один раз. и потом весело юзается.

>То как привильно считывать таблицы я так и не понял.
искать в районе lua_getfield(). которую применять на table в стеке. %-)
а lua_gettable() -- это для нумерованых индексов в таблице. внимательно кури мануал, там всё написано. %-)


 
Ketmar ©   (2007-04-30 22:00) [30]

пардон. забыл тэг закрыть. %-)


 
Kostafey ©   (2007-04-30 22:24) [31]

> напиши так: WriteLn(WriteLn("text"));. не удивительная ли
> конструкция? %-)

Я ж исправился: [28] Kostafey ©   (30.04.07 21:11):
showmessage(inttostr(luaL_dostring(LuaS, "print("Hellow World")")));


> кто тебе наврал, что print() возвращает какой-то результат?

Результат возвращает не print, а luaL_dostring - успешно/неуспешно.

По поводу таблиц попробую еще с мануалом поколдовать...


 
Kostafey ©   (2007-04-30 23:36) [32]

все же не понятно:

void lua_gettable (lua_State *L, int index); - Pushes onto the stack the value t[k]
получается, что мы читаем значение [k] из таблицы, которая уже должна находится в стеке

А как же таблицу в стек помещать ? lua_pushtable - то нет

void lua_getfield (lua_State *L, int index, const char *k); - Pushes onto the stack the value t[k]
Опять получается поже самое, только для ассоциативного массива.

Саму таблицу-то как загружать ?


 
Kostafey ©   (2007-05-01 14:09) [33]

> [32] Kostafey ©   (30.04.07 23:36)

Все, разобрался.



Страницы: 1 вся ветка

Текущий архив: 2007.05.20;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.054 c
15-1176929722
Alx2
2007-04-19 00:55
2007.05.20
Программирование: теория и практика.


2-1178222132
Ламер 2.Х
2007-05-03 23:55
2007.05.20
Присловутый реестр XP


1-1174579137
DelphiLexx
2007-03-22 18:58
2007.05.20
Рассылка сообщений дочерним окнам


3-1173160550
Sansy
2007-03-06 08:55
2007.05.20
Сохранение отчёта в поток для FastReport


3-1172922633
---SerG---
2007-03-03 14:50
2007.05.20
Инсталятор для баз данных