11
votes

Comment lire un fichier INI codé UTF8?

J'ai un fichier INI au format UTF-8.

J'utilise Delphi 2010 pour lire le fichier INI et renseigner un TStringGrid avec les valeurs du fichier INI. P>

var
  ctr : Integer;
  AppIni : TIniFile;
begin
  AppIni := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'test.ini');
    for ctr := 1 to StringGrid1.RowCount do begin
        StringGrid1.Cells[0,ctr] := AppIni.ReadString('Column1','Row'+IntToStr(ctr),'');
        StringGrid1.Cells[1,ctr] := AppIni.ReadString('Column2','Row'+IntToStr(ctr),'');
    end;
  AppIni.Free;


3 Réponses :


16
votes

La classe tinifile est une enveloppe de l'API Windows pour les fichiers INI. Cela prend en charge les fichiers INI Unicode, mais uniquement si ces fichiers sont codés comme UTF-16. Michael Kaplan a plus de détails ici: fonction Unicode ini; Unicode Ini File?

Alors, vous n'avez pas de chance avec tinifile . Au lieu de cela, vous pouvez utiliser tmeminifile qui vous permet de Spécifier un codage dans son constructeur . La classe TMeminifile est une implémentation Delphes native du support de fichier INI. Il existe divers avantages et inconvénients entre les deux classes. Dans votre situation, seul tmeminifile peut répondre à vos besoins. Il ressemble donc à ses pros allant l'emporter sur ses inconvénients.


11 commentaires

David H dit "Seulement si ces fichiers sont codés comme UTF-16", pourtant TLAMA dit "Vous allez simplement passer à Tencoding.utf8". Alors, quel est-ce?


J'ai essayé d'utiliser TMeminifile au lieu de tinifile, mais lorsque j'essaie de sauvegarder une nouvelle INI, le fichier ne se crée jamais. Voici la création: appunicodeini: = meminifile.create (extracteFilePath (applicy.exename) + 'test.ini', texoding.unicode); Et voici la méthode d'écriture: appunicodeini.writestring ('Colonne1', 'rangée' + inttostr (itemno), s tringgrid1.cells [0, C TR]); Puis enfin appunicodeini.free; Pourtant aucun fichier n'est créé.


Nous sommes tous deux corrects. Tlama dit Pass Tencoding.utf8 à tmeminifile . Et je dis ça aussi. C'est mon deuxième paragraphe. Et je dis aussi au paragraphe 1 que vous ne pouvez pas utiliser tinifile car il ne prend en charge que UTF-16. Notez que tmeminifile et tinifile ne sont pas la même classe. Je pense que c'est là que vous êtes confus.


Je comprends que je ne peux pas utiliser d'tinifile. Où je suis confus, c'est que Tlama a fait référence à UTF8, alors que vous avez dit UTF16. De plus, en utilisant soit avec TMeminifile ne produit toujours aucune sortie. UTF8 n'est pas utf16.


Eureka! On dirait que quelqu'un m'a oublié de me dire d'insérer updatefile dans mon code, sinon rien ne sera écrit sur le disque! :-(


@ user1527613, personne n'a oublié de vous dire comment affleurer tmeminifile sur le disque simplement parce que vous avez commencé votre question avec "J'utilise Delphi 2010 pour lire le fichier INI" Eh bien, car vous n'étiez évidemment que la lecture des valeurs du fichier INI de votre exemple de code. La question que vous avez posée est répondue ici.


Eh bien, comme @tlama dit, vous avez dit que vous lisiez à partir du fichier. Vous n'avez pas demandé comment écrire. Quoi qu'il en soit, la documentation dit ceci: DOCWIKI.EMBARCADERO.com/LIBRATION /EN/...


@ user1527613 cherchez-vous plus que cette réponse?


Quels sont les inconvénients pour TMeminifile?


@DavidHeffernan Pourriez-vous élaborer le contre des fichiers INI avec TMeminifile? Pour moi rien ne vient à l'esprit ...


@Anoisheimer je n'en savais aucun.



2
votes
Uses IniFiles;

const
  SZ_APP_NAME = 'demo_test';

Procedure TForm1.GetSettings;
var
  _MemIniU: TMemIniFile;
  _SettingsPath: string;
begin
  try
    _SettingsPath := GetHomePath + PathDelim + SZ_APP_NAME + PathDelim;
    if ForceDirectories(_SettingsPath) then
    begin
      _MemIniU := TMemIniFile.Create(ChangeFileExt(_SettingsPath,
        'Settings.ini'), TEncoding.UTF8);
      try
        if _MemIniU.ReadInteger(SZ_APP_NAME, 'WindowLeft', -1) = -1 then
          Form1.Position := poScreenCenter
        else
        begin
          Form1.Left := _MemIniU.ReadInteger(SZ_APP_NAME, 'WindowLeft', 10);
          Form1.Top := _MemIniU.ReadInteger(SZ_APP_NAME, 'WindowTop', 10);
          Form1.Width := _MemIniU.ReadInteger(SZ_APP_NAME, 'WindowWidth', 594);
          Form1.Height := _MemIniU.ReadInteger(SZ_APP_NAME,
            'WindowHeight', 342);
        end;
          Edit1.Text := _MemIniU.ReadString(SZ_APP_NAME, 'UnicodeText', 'ąčę');
      finally
        _MemIniU.Free;
      end;
    end;
  except
    on E: Exception do
      MessageDlg(PWideChar(E.Message), TMsgDlgType.mtError,
        [TMsgDlgBtn.mbOK], 0);
  end;
end;

Procedure TForm1.SaveSettings;
var
  _MemIniU: TMemIniFile;
  _SettingsPath: string;
begin
  try
    _SettingsPath := GetHomePath + PathDelim + SZ_APP_NAME + PathDelim;
    _MemIniU := TMemIniFile.Create(ChangeFileExt(_SettingsPath, 'Settings.ini'),
      TEncoding.UTF8);
    try
      if Form1.WindowState <> TWindowState.wsMaximized then
      begin
        _MemIniU.WriteInteger(SZ_APP_NAME, 'WindowLeft', Form1.Left);
        _MemIniU.WriteInteger(SZ_APP_NAME, 'WindowTop', Form1.Top);
        _MemIniU.WriteInteger(SZ_APP_NAME, 'WindowWidth', Form1.Width);
        _MemIniU.WriteInteger(SZ_APP_NAME, 'WindowHeight', Form1.Height);
        _MemIniU.WriteString(SZ_APP_NAME, 'UnicodeText', Edit1.Text);
      end;
      _MemIniU.UpdateFile;
    finally
      _MemIniU.Free;
    end;
  except
    on E: Exception do
      MessageDlg(PWideChar(E.Message), TMsgDlgType.mtError,
        [TMsgDlgBtn.mbOK], 0);
  end;
end;

0 commentaires

0
votes

dans une application était que j'utilisais tinifile code> J'avais la nécessité de commencer à stocker des caractères Unicode.

Pour ce faire, j'ai simplement changé le type de variable de tinifile code> à TMeminifile CODE> et dans le constructeur, après le nom de fichier, j'ai ajouté le deuxième paramètre Tencoding.utf8 code>. Puis, avant de libérer l'objet que j'ai appelé updatefile code>. Si le fichier INI est ouvert pour la lecture, appelez à updatefile code> n'est pas nécessaire. P>

// ANSI version
var myIniFile: TIniFile;
begin
  myIniFIle := TIniFile.Create('c:\Temp\MyFile.ini');
  myIniFile.WriteString(par1,par2,par3);
  // [...]
  myIniFile.Free;
end


// Unicode version
//1) "Mem" added here
var myIniFile: TMemIniFile; 
begin
  // 2) Enconding added
  myIniFIle := TIniFile.Create('c:\Temp\MyFile.ini', TEncoding.UTF8); 
  myIniFile.WriteString(par1,par2,par3);
  // [...]
  // 3) call to UpdateFile to save to disc the changes
  myIniFile.UpdateFile; 
  myIniFile.Free;
end


0 commentaires