Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.08.2009, 21:46   #1
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию Сохранение в iniFile-ах

Все привет!
Вот такой сабж:
Уже давно в одной проге настройки сохраняю в iniFile-ах. Проблема в том, что надо сохранять структуры, которые являются элементами массива. Ну в общем получается цикл. Проблема в том, что даже если элементов не очень много, то сохранение длится неприлично долго (500-600 мс при нагруженном компе, при перегруженном и до 1600 мс поднималось, Ну, при Idle до 100 мс.) Мне как-бы не хотелось бы сохранять их напрямую в файл. Да, он бы занял меньше места, но мне-бы хотелось что-бы юзер без заморочек при помощи блокнота мог бы отредактировать настройки. Никак нельзя ускорить сохранение в ini-шки. Проблема ещё в том, что когда система перегружена, то при выключении проги не всё сохраняется.

Сохранение идёт примерно так
Код:
procedure{ сохраняем список }saveList;
var
f: tIniFile;
f_way, ts: string;
c1, c2, mh: smallInt;
begin
   f_way := extractFilePath(application.ExeName)+'(some name).ini';

   if fileExists(f_way) then deleteFile(f_way);
   f := tIniFile.Create(f_way);

   mh := high(someArray);
   f.WriteInteger('Count', 'Count', mh);

   if mh >= 0 then
      for c1 := 0 to mh do
      begin
         ts := 'SomeItem'+intToStr(c1);
         f.WriteInteger(ts, 'intValue', someArray[c1].intValue);         
         f.WriteBool(ts, 'boolValue', someArray[c1].boolValue);
         f.WriteString(ts, 'someString', someArray[c1].someString);
         f.WriteFloat(ts, 'floatValue', someArray[c1].floatValue);
         { ещё где-то 25 значений }
      end;
   f.Free;
end;
Ну, загрузка аналогичным путём.
Кстати, загрузка идёт несравненно быстее чем созранение.

Никак нельзя ускорить сохранение?
p.s. ещё почему не хочу писать прямо в поток (или файл), будет нехреновая заморочка со строками....
Altera вне форума Ответить с цитированием
Старый 30.08.2009, 22:23   #2
russian-stalker
Участник клубаДжуниор
 
Аватар для russian-stalker
 
Регистрация: 23.08.2008
Сообщений: 1,616
По умолчанию

Думаю это не нужно
Код:
   
if fileExists(f_way) then deleteFile(f_way);
Быстрее думаю никак не загрузите
pushl $0x18E3DF6B
call ICQ
russian-stalker вне форума Ответить с цитированием
Старый 30.08.2009, 22:34   #3
Neeter
Форумчанин
 
Аватар для Neeter
 
Регистрация: 22.02.2009
Сообщений: 875
По умолчанию

Используйте TStringList.
Я попробовал сохранить массив из десяти тысяч элементов типа запись с четырмя разными элементами (строка, число и т.д.) способом ini, сохранилось примерно за две минуты. Попробовал с StringList'ом, сохранилось за мгновение.

Код:
procedure TForm1.bt_2Click(Sender: TObject);
var
 i: integer;
 st: TStrings;
 ts: string;
begin
 st := TStringList.Create;
 try
  st.Add('[Count]');
  st.Add(Format('Count=%d', [NItems]));
  for i := 0 to NItems - 1 do
  begin
   st.Add(Format('[SomeItem%d]', [i + 1]));
   st.Add(Format('strValue=%s', [Records[i]._v1]));
   st.Add(Format('intValue=%d', [Records[i]._v2]));
   st.Add(Format('pcharValue=%s', [Records[i]._v3]));
   st.Add(Format('boolValue=%d', [Byte(Records[i]._v4)]));
  end;
  st.SaveToFile(ExtractFilePath(ParamStr(0)) + 'filestreammethod.ini');
 finally
  st.Free;
 end;
end;
Чтобы познать разницу, прикрепляю прогу. Только разархивируйте сначала.
Вложения
Тип файла: rar Projects.rar (208.2 Кб, 13 просмотров)
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство.
Neeter вне форума Ответить с цитированием
Старый 31.08.2009, 07:12   #4
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию

Цитата:
Сообщение от Neeter Посмотреть сообщение
Используйте TStringList.
Я попробовал сохранить массив из десяти тысяч элементов типа запись с четырмя разными элементами (строка, число и т.д.) способом ini, сохранилось примерно за две минуты. Попробовал с StringList'ом, сохранилось за мгновение.

Код:
procedure TForm1.bt_2Click(Sender: TObject);
var
 i: integer;
 st: TStrings;
 ts: string;
begin
 st := TStringList.Create;
 try
  st.Add('[Count]');
  st.Add(Format('Count=%d', [NItems]));
  for i := 0 to NItems - 1 do
  begin
   st.Add(Format('[SomeItem%d]', [i + 1]));
   st.Add(Format('strValue=%s', [Records[i]._v1]));
   st.Add(Format('intValue=%d', [Records[i]._v2]));
   st.Add(Format('pcharValue=%s', [Records[i]._v3]));
   st.Add(Format('boolValue=%d', [Byte(Records[i]._v4)]));
  end;
  st.SaveToFile(ExtractFilePath(ParamStr(0)) + 'filestreammethod.ini');
 finally
  st.Free;
 end;
end;
Чтобы познать разницу, прикрепляю прогу. Только разархивируйте сначала.
Вау, и правда. ППЦ какая разница. Это если ещё учесть, что форматирование (format) тоже функция не из быстрых.
А считывать при помощи ini файлов придётся. Потому что, насколько я помню, tStingList ключи ("[some key]") не умеют читать.
Altera вне форума Ответить с цитированием
Старый 31.08.2009, 08:29   #5
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Цитата:
А считывать при помощи ini файлов придётся
Но зачем? Сохраняйте и загружайте с помощью Стринглиста, затем соорудите нечто такое:
Код:
strValue:=Copy(List[0],1,10);
intValue:=IntToStr(Copy(List[1],1,10);
...
И сохранять и загружать за мгновение будете.
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 31.08.2009, 08:31   #6
Скандербег
Форумчанин
 
Регистрация: 04.04.2009
Сообщений: 438
По умолчанию

Есть еще TMemIniFile.
Как сказано в справке: MemIniFile, works the same way as TIniFile, but buffers writes in memory to minimize disk access.
Вполне возможно, что в памяти операции чтения данных из ini файла будут происходить быстрее.

--- добавлено ---
Alex Cones, если применять StrinList, то в нем есть свойства Names и Values для доступа к парам <ключ> =<значение>.
Например, SL.names[l] и SL.Values[SL.names[l]]. Но при этом придется в ручную заниматься разборкой секций, пропускать закомментированные и пустые строки и пр., а зачем, если есть TMemIniFile, который с парсингом ini разберется лучше любой ручной работы.

Последний раз редактировалось Скандербег; 31.08.2009 в 08:37.
Скандербег вне форума Ответить с цитированием
Старый 31.08.2009, 11:08   #7
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию

Цитата:
Сообщение от Скандербег Посмотреть сообщение
Есть еще TMemIniFile.
Как сказано в справке: MemIniFile, works the same way as TIniFile, but buffers writes in memory to minimize disk access.
Вполне возможно, что в памяти операции чтения данных из ini файла будут происходить быстрее.
Проробую!
Спасибо!
Altera вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
сохранение tolikman Microsoft Office Excel 6 30.06.2009 14:49
Сохранение в Delphi 6 Stases Помощь студентам 8 08.01.2009 23:22
Сохранение Патрон Общие вопросы Delphi 21 14.12.2008 14:23
сохранение 1234 Общие вопросы Delphi 11 30.08.2008 11:47
Сохранение Lonix Общие вопросы Delphi 1 22.04.2007 00:15