Delphi - чтение файла в StringList, затем удаление и запись в файл - PullRequest
4 голосов
/ 09 января 2011

В настоящее время я работаю над программой для генерации хешей файлов в Delphi 2010. В рамках этого у меня есть возможность создавать пользовательские пресеты, например, предопределенный выбор алгоритмов хэширования, которые пользователь может создавать / сохранять / удалять. У меня есть код создания и загрузки работает нормально. Он использует ComboBox и загружает из файла "fhpre.ini", внутри этого файла находятся пользовательские пресеты, сохраненные в формате: -

PresetName
PresetCode (12-значная строка, использующая 0 для не хэширования и 1 для do)

При загрузке приложения оно загружает данные из этого файла в ComboBox и массив с ItemIndex ComboBox, совпадающего с соответствующей правильной строкой 0 и 1 в массиве.

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

procedure TForm1.Panel23Click(Sender : TObject);

var
fil : textfile;
contents : TStringList;
x,i : integer;
filline : ansistring;
filestream : TFileStream;

begin //Start Procedure

//Load data into StringList
contents := TStringList.Create;
fileStream := TFileStream.Create((GetAppData+'\RFA\fhpre.ini'), fmShareDenyNone);
Contents.LoadFromStream(fileStream);
fileStream.Destroy();

//Search for relevant Preset
i := 0;
if ComboBox4.Text <> Contents[i] then
begin
Repeat
i := i + 1;
Until ComboBox4.Text = Contents[i];
end;

contents.Delete(i); //Delete Relevant Preset Name
contents.Delete(i); //Delete Preset Digit String

//Write StringList back to file.
AssignFile(fil,(GetAppData+'\RFA\fhpre.ini'));
ReWrite(fil);
for i := 0 to Contents.Count -1 do
WriteLn(Contents[i]);
CloseFile(fil);
Contents.Free;
end;

Однако, если это запустить, я получаю ошибку 105, когда она попадает в раздел WriteLn. Я знаю, что код не очень хорош, например, не имеет проверок для пресетов с тем же именем, но это произойдет, я хочу, чтобы сначала работал базовый код, затем можно настроить и добавить дополнительные проверки и т.д. *

Любая помощь будет оценена.

Ответы [ 3 ]

12 голосов
/ 09 января 2011

Вы знаете, я надеюсь, что TStringList имеет методы LoadFromFile и SaveToFile?

А если по каким-то причинам вы не можете использовать эти методы, зачем использовать поток для чтения, а WriteLn для записи?

Чтобы записать в файл с помощью WriteLn, вы должны указать файл в качестве первого аргумента:

 WriteLn(fil, Contents[i]);

без аргумента он пытается записать на консоль (которая, вероятно, недоступна в вашем приложении Windows). Ошибка 105: «Файл не открыт для вывода».

6 голосов
/ 09 января 2011

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

0 голосов
/ 11 января 2011

Вот как будет выглядеть окончательный код после реализации TStringlist.LoadFromFile и TStringList.SaveToFile. Возможно, это все еще принесет пользу от некоторой оптимизации, но это произойдет вовремя.

Procedure TForm1.Panel23Click(Sender : TObject);

var
contents : TStringList;
i : integer;

begin //Start Procedure

//Load data into StringList
Contents := TStringList.Create;
Contents.LoadFromFile((GetAppData+'\RFA\fhpre.ini'));

//Search for relevant Preset
i := 0;
if ComboBox4.Text <> Contents[i] then
begin
   Repeat
    i := i + 1;
   Until ComboBox4.Text = Contents[i];
end;


contents.Delete(i); //Delete Relevant Preset Name
contents.Delete(i); //Delete Preset Digit String
Contents.SaveToFile((GetAppData+'\RFA\fhpre.ini'));

AddPresetCombo(GetAppData+'\RFA\fhpre.ini');   //Populate Comobo With Presets From File
Form1.ComboBox4.ItemIndex := 0;
Contents.Free; 
end;   
...