如何在Delphi中存储可以在运行时更改的文件路径

row*_*lip 2 delphi file

我的程序允许用户更改主文件集的位置.目前我有一个文本文件,其中包含固定位置,其中包含其他文件的文件夹位置.然而,这似乎几乎打败了目的.有没有更好的方法来存储此文件路径?

Ken*_*ite 7

Delphi包含TRegistry类,这使得从Windows注册表保存和检索设置信息变得非常简单.

uses
  Registry;

const
  RegKey = 'Software\Your Company\Your App\';

procedure TForm1.SaveSettingsClick(Sender: TObject);
var
  Reg: TRegistry;
  DataDir: string;
begin
  // Use the result of SelectDirectory() or whatever means you use
  // to get the desired location from the user here. ExtractFilePath()
  // is only used as an example - it just gets the location of the
  // application itself and then appends a subdirectory name to it.
  DataDir:= ExtractFilePath(Application.ExeName) + 'Data\';
  Reg := TRegistry.Create;
  try
    if Reg.OpenKey(RegKey, True) then
      Reg.WriteString('DataDir', DataDir);
  finally
    Reg.Free;
  end;
end;

procedure TForm1.GetSettingsClick(Sender: TObject);
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create;
  try
    if Reg.OpenKey(RegKey, False) then
      Label1.Caption := Reg.ReadString('DataDir');
  finally
    Reg.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

正如@SirRufo在评论中提到的那样,Delphi也有TRegistryIniFile,它作为注册表函数的包装器,允许您在不了解注册表结构的情况下使用它.(它的用法类似于TIniFile/TMemIniFile,我接下来会介绍它.)

如果您不想使用注册表,您也可以非常轻松地使用INI(文本文件).Delphi支持TIniFile中的标准(基于WinAPI)INI文件,以及它自己(和IMO更好实现)的TMemIniFile.两者都相当兼容,所以我将在这里演示只使用TMemIniFile.

(用于读/写的位置是为了简单.实际上,您应该使用%APPDATA%目录的相应子文件夹,通过使用或常量调用SHGetKnownFolderPath获得.)FOLDERID_RoamingAppDataFOLDERID_LocalAppData

uses
  IniFiles;

// Writing
var
  Ini: TMemIniFile;
  RootDir: string;
begin
  RootDir := ExtractFilePath(Application.ExeName);
  Ini := TMemIniFile.Create(TheFile);
  try
    Ini.WriteString('Settings', 'DataDir', RootDir + 'Data\');
    Ini.UpdateFile;
  finally
    Ini.Free;
  end;
end;

// Reading
var
  Ini: TMemIniFile;
  RootDir: string;
begin
  RootDir := ExtractFilePath(Application.ExeName);
  Ini := TMemIniFile.Create(TheFile);   // The file is your ini file name with path
  try
    DataDir := Ini.ReadString('Settings', 'DataDir', RootDir);
    if DataDir = '' then
      DataDir := RootDir;  // No user specified location. Use app's dir
  finally
    Ini.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)