2017-08-09 1 views
1

J'ai recherché ici et je n'ai pas trouvé de réponse à mon problème, j'ai un programme qui lit un rapport (fichier txt) et remplit automatiquement des cellules spécifiques d'une feuille de calcul dans un classeur . J'ai créé un fichier ini que l'utilisateur mettra à jour au fur et à mesure des besoins. Le problème que je rencontre est que je veux lire le fichier ini et enregistrer le contenu de certaines sections dans leurs propres listes. Voici mon code:Comment lire et enregistrer le fichier ini dans une liste

public class IniFile 
{ 

    [DllImport("kernel32")] 
    static extern int GetPrivateProfileString(string Section, string Key, 
      string Value, StringBuilder Result, int Size, string FileName); 


    [DllImport("kernel32")] 
    static extern int GetPrivateProfileString(string Section, int Key, 
      string Value, [MarshalAs(UnmanagedType.LPArray)] byte[] Result, 
      int Size, string FileName); 


    [DllImport("kernel32")] 
    static extern int GetPrivateProfileString(int Section, string Key, 
      string Value, [MarshalAs(UnmanagedType.LPArray)] byte[] Result, 
      int Size, string FileName); 

    public string path; 
    public IniFile(string INIPath) 
    { 
     path = INIPath; 
    } 

    public string[] GetSectionNames() 
    { 
     for (int maxsize = 500; true; maxsize *= 2) 
     { 
      byte[] bytes = new byte[maxsize]; 
      int size = GetPrivateProfileString(0, "", "", bytes, maxsize, path); 

      if (size < maxsize - 2) 
      { 
       string Selected = Encoding.ASCII.GetString(bytes, 0, 
           size - (size > 0 ? 1 : 0)); 
       return Selected.Split(new char[] { '\0' }); 
      } 
     } 
    } 

    public string[] GetEntryKeyNames(string section) 
    { 
     for (int maxsize = 500; true; maxsize *= 2) 
     { 
      byte[] bytes = new byte[maxsize]; 
      int  size  = GetPrivateProfileString(section, 0, "", bytes, maxsize, path); 

      if (size < maxsize - 2) 
      { 
       string entries = Encoding.ASCII.GetString(bytes, 0, 
           size - (size > 0 ? 1 : 0)); 
       return entries.Split(new char[] { '\0' }); 
      } 
     } 
    } 

    public object GetEntryKeyValue(string section, string entry) 
    { 
     for (int maxsize = 250; true; maxsize *= 2) 
     { 
      StringBuilder result = new StringBuilder(maxsize); 
      int   size  = GetPrivateProfileString(section, entry, "", 
           result, maxsize, path); 
      if (size < maxsize - 1) 
      { 
       return result.ToString(); 
      } 
     } 
    } 
} 

}

Voici mon code en cours d'utilisation:

List<string> PlacesList= new List<string>(); 
    List<string> PositionsList= new List<string>(); 

    private void btnReadini_Click(object sender, EventArgs e) 
    { 
     IniFile INI = new IniFile(@"C:\Races.ini"); 
     try 
     { 
      string[] SectionHeader = INI.GetSectionNames(); 
      if (SectionHeader != null) 
      { 
       foreach (string SecHead in SectionHeader) 
       { 
        listBox1.Items.Add(""); 
        listBox1.Items.Add("[" +SecHead+"]"); 

        string[] Entry = INI.GetEntryKeyNames(SecHead); 
        if (Entry != null) 
        { 
         foreach (string EntName in Entry) 
         { 
          listBox1.Items.Add(EntName +"=" + 
             INI.GetEntryKeyValue(SecHead, EntName)); 
         } 
        } 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      listBox1.Items.Add("Error: " + ex); 
     } 
    } 

Voici un exemple de fichier ini

[Places] 
IOM=Isle of man 
UK=United Kingdom 
IRE=Ireland 
[Races] 
IOM=7 
UK=6 
[Positions] 
WN=Win 
2nd=Second 
3rd=Third 
4th=Fourth 

Je peux lire actuellement le ini fichier et l'afficher dans mon listBox, ce que je souhaite faire maintenant est de sauvegarder le nom et la valeur de la section [Places] dans une liste appelée Place sListez et enregistrez le nom et la valeur de Positions dans une liste appelée PositionsList. Avec la classe actuelle, je peux lire toutes les sections, les clés et les valeurs, mais comment puis-je obtenir uniquement les données que je veux dans les listes?

Répondre

1

Vous étiez proche du code ci-dessus, mais plutôt que de parcourir toutes les sections, vous pouvez simplement demander celles dont vous avez besoin (la même chose pourrait s'appliquer aux entrées si nécessaire).

List<string> PlacesList= new List<string>(); 
List<string> PositionsList= new List<string>(); 

public void btnReadini_Click(object sender, EventArgs e) 
{ 
    PlacesList = ListEntries("Places"); 
    PositionsList = ListEntries("Positions"); 
} 

public List<string> ListEntries(string sectionName) 
{ 
    IniFile INI = new IniFile(@"C:\Races.ini"); 
    List<string> entries = null; 

    string[] Entry = INI.GetEntryKeyNames(sectionName); 
    if (Entry != null) 
    { 
     entries = new List<string>(); 

     foreach (string EntName in Entry) 
     { 
      entries.Add(EntName + "=" + INI.GetEntryKeyValue(sectionName, EntName)); 
     } 
    } 

    return entries; 
} 

Cependant, au lieu de stocker les données dans une liste, vous devriez regarder à l'aide d'un Dictionary, vous pouvez utiliser la clé pour rechercher la valeur.

public Dictionary<string, string> ListEntries(string sectionName) 
{ 
    IniFile INI = new IniFile(@"C:\Races.ini"); 

    string[] Entry = INI.GetEntryKeyNames(sectionName); 
    var entries = Entry .Where(x => !string.IsNullOrEmpty(x)) 
         .ToDictionary(m => m, 
             m => INI.GetEntryKeyValue(sectionName, m)); 

    return entries; 
} 
+0

Génial, merci Jon Clarke – Oxlade

+0

Super! S'il vous plaît pouvez-vous marquer cela comme la réponse afin que d'autres puissent le trouver facilement à l'avenir ... –

+0

Désolé Jon Clarke, je pensais que j'avais. C'est marqué maintenant. Merci – Oxlade