RemObjects possède une bibliothèque Delphi Prism appelée ShineOn qui expédie une classe de fichiers INI similaire. Mais vous devez avoir Delphi Prism pour le compiler pour .NET à partir des sources car il n'y a pas encore d'assembly compilé disponible. code.remobjects.com/p/shineon
Lex Li
1
Vous avez le même problème et créé ma propre bibliothèque pour analyser les fichiers ini: github.com/rickyah/ini-parser J'espère que cela aide
Les créateurs du framework .NET souhaitent que vous utilisiez des fichiers de configuration basés sur XML, plutôt que des fichiers INI. Donc non, il n'y a pas de mécanisme intégré pour les lire.
Vous pouvez écrire votre propre gestionnaire INI, qui est la méthode laborieuse à l'ancienne. Il vous donne plus de contrôle sur l'implémentation, que vous pouvez utiliser pour le meilleur ou pour le pire. Voir par exemple une classe de gestion de fichiers INI utilisant C #, P / Invoke et Win32 .
Bien qu'il soit vrai que les fichiers de configuration XML sont le chemin à parcourir, ce n'est toujours pas une réponse à la question, ou c'est VLQ pour le lien uniquement.
Danny Beckett
6
@aloneguid Je dirais que le grand ensemble de fonctionnalités disponibles a en fait contribué aux fichiers de configuration .NET finissant par être des monstres étranges avec beaucoup de magie. Ils sont devenus du «code dans le fichier de configuration», ce qui entraîne beaucoup de complexité, des comportements étranges et rend la gestion de la configuration plus difficile. (Je vous regarde, les «fournisseurs» de bases de données et les chaînes de connexion.) Les fichiers INI sont donc également généralement meilleurs pour l'édition non manuelle.
jpmc26
1
j'aime l'ancienne méthode (P / Inovke) et vous pouvez utiliser unicode avec l'ancienne méthode comme celle-ci: File.WriteAllBytes (chemin, nouvel octet [] {0xFF, 0xFE});
sailfish009
2
Bon paquet mais ça pourrait être mieux. Il ne peut pas analyser complètement une valeur qui contient '=' Ou '\ n'
Ahmad Behjati
211
Préface
Tout d'abord, lisez ce billet de blog MSDN sur les limites des fichiers INI . Si cela convient à vos besoins, lisez la suite.
Il s'agit d'une implémentation concise que j'ai écrite, en utilisant la version originale de Windows P / Invoke, elle est donc prise en charge par toutes les versions de Windows avec .NET installé (c'est-à-dire Windows 98 - Windows 10). Je le publie dans le domaine public - vous êtes libre de l'utiliser commercialement sans attribution.
La petite classe
Ajoutez une nouvelle classe appelée IniFile.csà votre projet:
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;// Change this to match your program's normal namespace
namespace MyProg{classIniFile// revision 11{stringPath;string EXE =Assembly.GetExecutingAssembly().GetName().Name;[DllImport("kernel32",CharSet=CharSet.Unicode)]staticexternlongWritePrivateProfileString(stringSection,stringKey,stringValue,stringFilePath);[DllImport("kernel32",CharSet=CharSet.Unicode)]staticexternintGetPrivateProfileString(stringSection,stringKey,stringDefault,StringBuilderRetVal,intSize,stringFilePath);publicIniFile(stringIniPath=null){Path=newFileInfo(IniPath?? EXE +".ini").FullName;}publicstringRead(stringKey,stringSection=null){varRetVal=newStringBuilder(255);GetPrivateProfileString(Section?? EXE,Key,"",RetVal,255,Path);returnRetVal.ToString();}publicvoidWrite(stringKey,stringValue,stringSection=null){WritePrivateProfileString(Section?? EXE,Key,Value,Path);}publicvoidDeleteKey(stringKey,stringSection=null){Write(Key,null,Section?? EXE);}publicvoidDeleteSection(stringSection=null){Write(null,null,Section?? EXE);}publicboolKeyExists(stringKey,stringSection=null){returnRead(Key,Section).Length>0;}}}
Comment l'utiliser
Ouvrez le fichier INI de l'une des 3 manières suivantes:
// Creates or loads an INI file in the same directory as your executable// named EXE.ini (where EXE is the name of your executable)varMyIni=newIniFile();// Or specify a specific name in the current dirvarMyIni=newIniFile("Settings.ini");// Or specify a specific name in a specific dirvarMyIni=newIniFile(@"C:\Settings.ini");
Je suis un peu en retard, mais il manque une GetSections()méthode.
jusqu'au
2
Peut-être une valeur par défaut plus traditionnelle serait des fichiers .ini par application (et non par assemblage) comme Path.GetFullPath(IniPath ?? Path.ChangeExtension(Application.ExecutablePath, ".ini")).
Eugene Ryabtsev
3
Vraiment super ! Mettez-le sur github?
Emrys Myrooin
2
@danny Beckett, bien joué. C'est presque exactement la même chose que ce que j'ai utilisé au cours des dernières années um de .Net. Mise à jour depuis l'ancien code il y a des années.
Damian
10
Maintenant vieux, et autant que je respecte Raymond Chen, bon nombre des limitations de cet article étaient des limitations de la bibliothèque INI spécifique dans Windows, et non le format INI lui-même. D'autres, comme les autorisations granulaires, pourraient être facilement contournées via plusieurs fichiers. Une bibliothèque INI officielle et modernisée serait la bienvenue, même aujourd'hui.
L'auteur a créé une classe C # "Ini" qui expose deux fonctions de KERNEL32.dll. Ces fonctions sont: WritePrivateProfileStringet GetPrivateProfileString. Vous aurez besoin de deux espaces de noms: System.Runtime.InteropServiceset System.Text.
Étapes pour utiliser la classe Ini
Dans la définition de votre espace de noms de projet, ajoutez
using INI;
Créer un fichier INIF comme celui-ci
INIFile ini =newINIFile("C:\\test.ini");
Utilisez IniWriteValuepour écrire une nouvelle valeur dans une clé spécifique dans une section ou utilisez IniReadValuepour lire une valeur à partir d'une clé dans une section spécifique.
J'ai utilisé cette approche pendant un certain temps, mais les améliorations de sécurité à partir de Win7 ont à peu près tout tué pour moi. Vous pouvez toujours utiliser cette approche, mais vous devrez stocker le fichier .ini dans ProgramData et y faire lire / écrire votre application.
Jess
N'enregistrez pas les fichiers ini de configuration d'application dans ProgramData. Ils n'appartiennent ni au Registre ni à ProgramData. Les fichiers de configuration sont censés se trouver dans les dossiers LocalApplicationData.
using System;
using System.IO;
using System.Collections;publicclassIniParser{privateHashtable keyPairs =newHashtable();privateString iniFilePath;privatestructSectionPair{publicStringSection;publicStringKey;}/// <summary>/// Opens the INI file at the given path and enumerates the values in the IniParser./// </summary>/// <param name="iniPath">Full path to INI file.</param>publicIniParser(String iniPath){TextReader iniFile =null;String strLine =null;String currentRoot =null;String[] keyPair =null;
iniFilePath = iniPath;if(File.Exists(iniPath)){try{
iniFile =newStreamReader(iniPath);
strLine = iniFile.ReadLine();while(strLine !=null){
strLine = strLine.Trim().ToUpper();if(strLine !=""){if(strLine.StartsWith("[")&& strLine.EndsWith("]")){
currentRoot = strLine.Substring(1, strLine.Length-2);}else{
keyPair = strLine.Split(newchar[]{'='},2);SectionPair sectionPair;Stringvalue=null;if(currentRoot ==null)
currentRoot ="ROOT";
sectionPair.Section= currentRoot;
sectionPair.Key= keyPair[0];if(keyPair.Length>1)value= keyPair[1];
keyPairs.Add(sectionPair,value);}}
strLine = iniFile.ReadLine();}}catch(Exception ex){throw ex;}finally{if(iniFile !=null)
iniFile.Close();}}elsethrownewFileNotFoundException("Unable to locate "+ iniPath);}/// <summary>/// Returns the value for the given section, key pair./// </summary>/// <param name="sectionName">Section name.</param>/// <param name="settingName">Key name.</param>publicStringGetSetting(String sectionName,String settingName){SectionPair sectionPair;
sectionPair.Section= sectionName.ToUpper();
sectionPair.Key= settingName.ToUpper();return(String)keyPairs[sectionPair];}/// <summary>/// Enumerates all lines for given section./// </summary>/// <param name="sectionName">Section to enum.</param>publicString[]EnumSection(String sectionName){ArrayList tmpArray =newArrayList();foreach(SectionPair pair in keyPairs.Keys){if(pair.Section== sectionName.ToUpper())
tmpArray.Add(pair.Key);}return(String[])tmpArray.ToArray(typeof(String));}/// <summary>/// Adds or replaces a setting to the table to be saved./// </summary>/// <param name="sectionName">Section to add under.</param>/// <param name="settingName">Key name to add.</param>/// <param name="settingValue">Value of key.</param>publicvoidAddSetting(String sectionName,String settingName,String settingValue){SectionPair sectionPair;
sectionPair.Section= sectionName.ToUpper();
sectionPair.Key= settingName.ToUpper();if(keyPairs.ContainsKey(sectionPair))
keyPairs.Remove(sectionPair);
keyPairs.Add(sectionPair, settingValue);}/// <summary>/// Adds or replaces a setting to the table to be saved with a null value./// </summary>/// <param name="sectionName">Section to add under.</param>/// <param name="settingName">Key name to add.</param>publicvoidAddSetting(String sectionName,String settingName){AddSetting(sectionName, settingName,null);}/// <summary>/// Remove a setting./// </summary>/// <param name="sectionName">Section to add under.</param>/// <param name="settingName">Key name to add.</param>publicvoidDeleteSetting(String sectionName,String settingName){SectionPair sectionPair;
sectionPair.Section= sectionName.ToUpper();
sectionPair.Key= settingName.ToUpper();if(keyPairs.ContainsKey(sectionPair))
keyPairs.Remove(sectionPair);}/// <summary>/// Save settings to new file./// </summary>/// <param name="newFilePath">New file path.</param>publicvoidSaveSettings(String newFilePath){ArrayList sections =newArrayList();String tmpValue ="";String strToSave ="";foreach(SectionPair sectionPair in keyPairs.Keys){if(!sections.Contains(sectionPair.Section))
sections.Add(sectionPair.Section);}foreach(String section in sections){
strToSave +=("["+ section +"]\r\n");foreach(SectionPair sectionPair in keyPairs.Keys){if(sectionPair.Section== section){
tmpValue =(String)keyPairs[sectionPair];if(tmpValue !=null)
tmpValue ="="+ tmpValue;
strToSave +=(sectionPair.Key+ tmpValue +"\r\n");}}
strToSave +="\r\n";}try{TextWriter tw =newStreamWriter(newFilePath);
tw.Write(strToSave);
tw.Close();}catch(Exception ex){throw ex;}}/// <summary>/// Save settings back to ini file./// </summary>publicvoidSaveSettings(){SaveSettings(iniFilePath);}}
+1 pour compenser au-dessus du vote à la baisse. De quoi vous plaignez-vous vraiment? Il a dit l'avoir TROUVÉ. Le dévalorisez-vous pour ne pas en avoir trouvé un avec des accesseurs génériques et un constructeur de chaînes?
Tormod
1
@Tormod: J'aimerais pouvoir voter contre le commentaire. Il s'agit d'un forum technique lorsque nous votons sur des solutions, et non sur l'intention (manifestement positive). Si une solution proposée par Knuth lui-même avait des défauts, elle serait - et devrait - être signalée. Peu importe si la solution a été trouvée ou écrite par l'affiche.
ya23
7
Je pense que vous étirez la définition de «défaut». Si la solution ne met pas l'accent sur vos sensibilités, ne votez tout simplement pas. Je viens de laisser une note disant que j'ai déjà annulé son downvote afin que les 7 autres gars qui ont voté pour mon commentaire ne le fassent pas eux-mêmes.
Tormod
21
Le code dans la réponse de joerage est inspirant.
Malheureusement, il modifie la casse des caractères des touches et ne gère pas les commentaires. J'ai donc écrit quelque chose qui devrait être suffisamment robuste pour lire (uniquement) des fichiers INI très sales et permet de récupérer les clés telles quelles.
Il utilise LINQ, un dictionnaire de chaînes imbriqué insensible à la casse pour stocker les sections, les clés et les valeurs, et lire le fichier en une seule fois.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;classIniReader{Dictionary<string,Dictionary<string,string>> ini =newDictionary<string,Dictionary<string,string>>(StringComparer.InvariantCultureIgnoreCase);publicIniReader(string file){var txt =File.ReadAllText(file);Dictionary<string,string> currentSection =newDictionary<string,string>(StringComparer.InvariantCultureIgnoreCase);
ini[""]= currentSection;foreach(var line in txt.Split(new[]{"\n"},StringSplitOptions.RemoveEmptyEntries).Where(t =>!string.IsNullOrWhiteSpace(t)).Select(t => t.Trim())){if(line.StartsWith(";"))continue;if(line.StartsWith("[")&& line.EndsWith("]")){
currentSection =newDictionary<string,string>(StringComparer.InvariantCultureIgnoreCase);
ini[line.Substring(1, line.LastIndexOf("]")-1)]= currentSection;continue;}var idx = line.IndexOf("=");if(idx ==-1)
currentSection[line]="";else
currentSection[line.Substring(0, idx)]= line.Substring(idx +1);}}publicstringGetValue(string key){returnGetValue(key,"","");}publicstringGetValue(string key,string section){returnGetValue(key, section,"");}publicstringGetValue(string key,string section,string@default){if(!ini.ContainsKey(section))return@default;if(!ini[section].ContainsKey(key))return@default;return ini[section][key];}publicstring[]GetKeys(string section){if(!ini.ContainsKey(section))returnnewstring[0];return ini[section].Keys.ToArray();}publicstring[]GetSections(){return ini.Keys.Where(t => t !="").ToArray();}}
et merci de ne pas avoir mis ça catch (Exception ex) { throw ex; }dedans
Mark Schultheiss
1
Bien! Au moins certains changements sont nécessaires pour mieux fonctionner. Ligne 16: ini [""] = currentSection; À: // ini [""] = currentSection; Cela doit être supprimé car à chaque fois le premier élément [0] sera un segment vide en raison de cette initialisation. Ligne 36: currentSection [line.Substring (0, idx)] = line.Substring (idx + 1); À: currentSection [line.Substring (0, idx) .Trim ()] = line.Substring (idx + 1) .Trim (); La clé et les valeurs doivent être ajustées indépendamment, non seulement sur la ligne Trim. Dans INI, les fichiers de configuration similaires qui ajoutent généralement des paires K-> V ont tendance à aligner ces égaux à l'intérieur des sections. Je vous remercie!
LXSoft
Cela faisait longtemps. Merci beaucoup pour vos suggestions. Ils ont tous du sens et méritent ce code pour avoir un bon rafraîchissement.
Larry
13
Je veux introduire une bibliothèque IniParser que j'ai créée complètement en c #, donc elle ne contient aucune dépendance dans aucun OS, ce qui la rend compatible Mono. Open Source avec licence MIT - il peut donc être utilisé dans n'importe quel code.
Si vous avez seulement besoin d'un accès en lecture et non d'un accès en écriture et que vous utilisez le Microsoft.Extensions.Confiuration(fourni par défaut avec ASP.NET Core mais fonctionne également avec les programmes standard), vous pouvez utiliser le package NuGet Microsoft.Extensions.Configuration.Inipour importer des fichiers ini dans vos paramètres de configuration.
Juste pour ajouter que vous obtenez ensuite les clés avecConfiguration["keyname"]
kofifus
@scott, le problème que je rencontre est pour une raison quelconque, IIS ne le reconnaît pas lorsque l'application est en cours d'exécution. il est déployé, et là, mais n'est pas consommé. HTTP 500.30 est retourné et le journal de l'application IIS indique «le fichier de configuration est introuvable et n'est pas facultatif».
one.beat.consumer
3
Généralement, lorsque vous créez des applications à l'aide de C # et du framework .NET, vous n'utiliserez pas de fichiers INI. Il est plus courant de stocker les paramètres dans un fichier de configuration basé sur XML ou dans le registre. Cependant, si votre logiciel partage des paramètres avec une application héritée, il peut être plus facile d'utiliser son fichier de configuration, plutôt que de dupliquer les informations ailleurs.
Le framework .NET ne prend pas directement en charge l'utilisation des fichiers INI. Cependant, vous pouvez utiliser les fonctions de l'API Windows avec Platform Invocation Services (P / Invoke) pour écrire et lire à partir des fichiers. Dans ce lien, nous créons une classe qui représente les fichiers INI et utilise les fonctions de l'API Windows pour les manipuler. Veuillez passer par le lien suivant.
Restez en dehors du registre! Les données de configuration d'application ne doivent pas être enregistrées dans le registre.
Deegee
3
Si vous voulez juste un simple lecteur sans sections et autres DLL, voici une solution simple:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tool{publicclassConfig{Dictionary<string,string> values;publicConfig(string path){
values =File.ReadLines(path).Where(line =>(!String.IsNullOrWhiteSpace(line)&&!line.StartsWith("#"))).Select(line => line.Split(newchar[]{'='},2,0)).ToDictionary(parts => parts[0].Trim(), parts => parts.Length>1?parts[1].Trim():null);}publicstringValue(string name,stringvalue=null){if(values!=null&& values.ContainsKey(name)){return values[name];}returnvalue;}}}
Exemple d'utilisation:
file =newTool.Config(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)+"\\config.ini");
command = file.Value("command");
action = file.Value("action");stringvalue;//second parameter is default value if no key found with this namevalue= file.Value("debug","true");this.debug =(value.ToLower()=="true"||value=="1");value= file.Value("plain","false");this.plain =(value.ToLower()=="true"||value=="1");
Pendant ce temps, configurez le contenu du fichier (comme vous le voyez, prend en charge le symbole # pour le commentaire de ligne):
#command to run
command = php
#default script
action = index.php
#debug mode#debug = true#plain text mode#plain = false#icon = favico.ico
PeanutButter.INI est une classe empaquetée Nuget pour la manipulation de fichiers INI. Il prend en charge la lecture / écriture, y compris les commentaires - vos commentaires sont conservés lors de l'écriture. Il semble être relativement populaire, testé et facile à utiliser. C'est aussi totalement gratuit et open-source.
Avertissement: je suis l'auteur de PeanutButter.INI.
Je suis en retard pour rejoindre le parti, mais j'ai eu le même problème aujourd'hui et j'ai écrit l'implémentation suivante:
using System.Text.RegularExpressions;staticbool match(thisstring str,string pat,outMatch m)=>(m =Regex.Match(str, pat,RegexOptions.IgnoreCase)).Success;staticvoidMain(){Dictionary<string,Dictionary<string,string>> ini =newDictionary<string,Dictionary<string,string>>();string section ="";foreach(string line inFile.ReadAllLines(.........))// read from file{string ln =(line.Contains('#')? line.Remove(line.IndexOf('#')): line).Trim();if(ln.match(@"^[ \t]*\[(?<sec>[\w\-]+)\]",outMatch m))
section = m.Groups["sec"].ToString();elseif(ln.match(@"^[ \t]*(?<prop>[\w\-]+)\=(?<val>.*)",out m)){if(!ini.ContainsKey(section))
ini[section]=newDictionary<string,string>();
ini[section][m.Groups["prop"].ToString()]= m.Groups["val"].ToString();}}// access the ini file as follows:string content = ini["section"]["property"];}
Il faut noter que cette implémentation ne gère pas les sections ou propriétés qui ne sont pas trouvées. Pour ce faire, vous devez étendre la Dictionary<,>classe-pour gérer les clés non trouvées.
Pour sérialiser une instance de Dictionary<string, Dictionary<string, string>>en un .ini-file, j'utilise le code suivant:
string targetpath =.........;Dictionary<string,Dictionary<string,string>> ini =........;StringBuilder sb =newStringBuilder();foreach(string section in ini.Keys){
sb.AppendLine($"[{section}]");foreach(string property in ini[section].Keys)
sb.AppendLine($"{property}={ini[section][property]");}File.WriteAllText(targetpath, sb.ToString());
Dans le cas où ce n'est pas évident en regardant au niveau supérieur de la bibliothèque (ce n'était pas évident pour moi!), La classe IniDcoument et al sont dans ComLib.IO.
Tim Keating
2
Pour quiconque regarde cette route, CommonLibrary.NET ne semble pas suivre les conventions .INI. Il utilise un signe deux-points ":" comme délimiteur au lieu du signe égal, et il ne gère pas les commentaires (le début d'une ligne avec un point-virgule ou un signe dièse entraînera l'échec de l'analyse).
jmmr
2
Voici ma propre version, utilisant des expressions régulières. Ce code suppose que chaque nom de section est unique - si ce n'est pas le cas - il est logique de remplacer Dictionary par List. Cette fonction prend en charge les commentaires de fichiers .ini, en commençant par ';' personnage. La section démarre normalement [section], et les paires valeur / clé viennent également normalement "clé = valeur". Même hypothèse que pour les sections - le nom de la clé est unique.
/// <summary>/// Loads .ini file into dictionary./// </summary>publicstaticDictionary<String,Dictionary<String,String>> loadIni(String file){Dictionary<String,Dictionary<String,String>> d =newDictionary<string,Dictionary<string,string>>();String ini =File.ReadAllText(file);// Remove comments, preserve linefeeds, if end-user needs to count line number.
ini =Regex.Replace(ini,@"^\s*;.*$","",RegexOptions.Multiline);// Pick up all lines from first section to another sectionforeach(Match m inRegex.Matches(ini,"(^|[\r\n])\\[([^\r\n]*)\\][\r\n]+(.*?)(\\[([^\r\n]*)\\][\r\n]+|$)",RegexOptions.Singleline)){String sectionName = m.Groups[2].Value;Dictionary<String,String> lines =newDictionary<String,String>();// Pick up "key = value" kind of syntax.foreach(Match l inRegex.Matches(ini,@"^\s*(.*?)\s*=\s*(.*?)\s*$",RegexOptions.Multiline)){String key = l.Groups[1].Value;Stringvalue= l.Groups[2].Value;// Open up quotation if any.value=Regex.Replace(value,"^\"(.*)\"$","$1");if(!lines.ContainsKey(key))
lines[key]=value;}if(!d.ContainsKey(sectionName))
d[sectionName]= lines;}return d;}
Cette fonction ne fonctionne pas, pour moi: elle oublie une section sur deux. J'ai essayé avec et sans lignes vides avant [Section].
iksess
pouvez-vous copier un exemple de votre .ini qui ne fonctionne pas?
TarmoPikaro
-3
Voici ma classe, fonctionne comme un charme:
publicstaticclassIniFileManager{[DllImport("kernel32")]privatestaticexternlongWritePrivateProfileString(string section,string key,string val,string filePath);[DllImport("kernel32")]privatestaticexternintGetPrivateProfileString(string section,string key,string def,StringBuilder retVal,int size,string filePath);[DllImport("kernel32.dll")]privatestaticexternintGetPrivateProfileSection(string lpAppName,byte[] lpszReturnBuffer,int nSize,string lpFileName);/// <summary>/// Write Data to the INI File/// </summary>/// <PARAM name="Section"></PARAM>/// Section name/// <PARAM name="Key"></PARAM>/// Key Name/// <PARAM name="Value"></PARAM>/// Value NamepublicstaticvoidIniWriteValue(string sPath,stringSection,stringKey,stringValue){WritePrivateProfileString(Section,Key,Value, sPath);}/// <summary>/// Read Data Value From the Ini File/// </summary>/// <PARAM name="Section"></PARAM>/// <PARAM name="Key"></PARAM>/// <PARAM name="Path"></PARAM>/// <returns></returns>publicstaticstringIniReadValue(string sPath,stringSection,stringKey){StringBuilder temp =newStringBuilder(255);int i =GetPrivateProfileString(Section,Key,"", temp,255, sPath);return temp.ToString();}
}
L'utilisation est évitée car c'est une classe statique, il suffit d'appeler IniFileManager.IniWriteValue pour lire une section ou IniFileManager.IniReadValue pour lire une section.
Cette approche a déjà été montrée et expliquée dans une autre réponse . Qu'ajoute votre réponse qui n'est pas couverte par celle-ci?
Palec
Attention, cela ne fonctionne que si le fichier .ini est enregistré en UNICODE (16bit LE). Utilisez Notepad ++ pour convertir le texte en unicode, car si vous l'enregistrez en UTF-8, cela ne fonctionnera pas. ANSI est également acceptable, mais vous ne pouvez pas lire les lettres accentuées
user2991288
-6
Vous devez lire et écrire des données à partir de fichiers xml car vous pouvez enregistrer un objet entier en xml et vous pouvez également remplir un objet à partir d'un xml enregistré. Il vaut mieux manipuler des objets facilement.
Les liens vers des ressources externes sont encouragés, mais veuillez ajouter du contexte autour du lien afin que vos collègues utilisateurs aient une idée de ce que c'est et pourquoi il est là. Citez toujours la partie la plus pertinente d'un lien important, au cas où le site cible serait inaccessible ou se déconnecterait définitivement.
davejal
Je pense que les titres des liens sont très clairs sur ses références / contexte. Si vous pensez que cela ne suffit pas, n'hésitez pas à le modifier.
Réponses:
Les créateurs du framework .NET souhaitent que vous utilisiez des fichiers de configuration basés sur XML, plutôt que des fichiers INI. Donc non, il n'y a pas de mécanisme intégré pour les lire.
Il existe cependant des solutions tierces.
la source
Préface
Tout d'abord, lisez ce billet de blog MSDN sur les limites des fichiers INI . Si cela convient à vos besoins, lisez la suite.
Il s'agit d'une implémentation concise que j'ai écrite, en utilisant la version originale de Windows P / Invoke, elle est donc prise en charge par toutes les versions de Windows avec .NET installé (c'est-à-dire Windows 98 - Windows 10). Je le publie dans le domaine public - vous êtes libre de l'utiliser commercialement sans attribution.
La petite classe
Ajoutez une nouvelle classe appelée
IniFile.cs
à votre projet:Comment l'utiliser
Ouvrez le fichier INI de l'une des 3 manières suivantes:
Vous pouvez écrire des valeurs comme ceci:
Pour créer un fichier comme celui-ci:
Pour lire les valeurs du fichier INI:
En option, vous pouvez définir
[Section]
:Pour créer un fichier comme celui-ci:
Vous pouvez également vérifier l'existence d'une clé comme ceci:
Vous pouvez supprimer une clé comme ceci:
Vous pouvez également supprimer une section entière (y compris toutes les clés) comme ceci:
N'hésitez pas à commenter toutes les améliorations!
la source
GetSections()
méthode.Path.GetFullPath(IniPath ?? Path.ChangeExtension(Application.ExecutablePath, ".ini"))
.Cet article sur CodeProject " Une classe de gestion de fichiers INI utilisant C # " devrait vous aider.
L'auteur a créé une classe C # "Ini" qui expose deux fonctions de KERNEL32.dll. Ces fonctions sont:
WritePrivateProfileString
etGetPrivateProfileString
. Vous aurez besoin de deux espaces de noms:System.Runtime.InteropServices
etSystem.Text
.Étapes pour utiliser la classe Ini
Dans la définition de votre espace de noms de projet, ajoutez
Créer un fichier INIF comme celui-ci
Utilisez
IniWriteValue
pour écrire une nouvelle valeur dans une clé spécifique dans une section ou utilisezIniReadValue
pour lire une valeur à partir d'une clé dans une section spécifique.Remarque: si vous partez de zéro, vous pouvez lire cet article MSDN : Comment: ajouter des fichiers de configuration d'application à des projets C # . C'est une meilleure façon de configurer votre application.
la source
J'ai trouvé cette implémentation simple:
http://bytes.com/topic/net/insights/797169-reading-parsing-ini-file-c
Fonctionne bien pour ce dont j'ai besoin.
Voici comment vous l'utilisez:
Voici le code:
la source
Le code dans la réponse de joerage est inspirant.
Malheureusement, il modifie la casse des caractères des touches et ne gère pas les commentaires. J'ai donc écrit quelque chose qui devrait être suffisamment robuste pour lire (uniquement) des fichiers INI très sales et permet de récupérer les clés telles quelles.
Il utilise LINQ, un dictionnaire de chaînes imbriqué insensible à la casse pour stocker les sections, les clés et les valeurs, et lire le fichier en une seule fois.
la source
catch (Exception ex) { throw ex; }
dedansJe veux introduire une bibliothèque IniParser que j'ai créée complètement en c #, donc elle ne contient aucune dépendance dans aucun OS, ce qui la rend compatible Mono. Open Source avec licence MIT - il peut donc être utilisé dans n'importe quel code.
Vous pouvez vérifier la source dans GitHub , et c'est également disponible en tant que package NuGet
Il est fortement configurable et très simple à utiliser .
Désolé pour le plug sans vergogne, mais j'espère qu'il peut être utile à quiconque revisite cette réponse.
la source
Si vous avez seulement besoin d'un accès en lecture et non d'un accès en écriture et que vous utilisez le
Microsoft.Extensions.Confiuration
(fourni par défaut avec ASP.NET Core mais fonctionne également avec les programmes standard), vous pouvez utiliser le package NuGetMicrosoft.Extensions.Configuration.Ini
pour importer des fichiers ini dans vos paramètres de configuration.la source
Configuration["keyname"]
Généralement, lorsque vous créez des applications à l'aide de C # et du framework .NET, vous n'utiliserez pas de fichiers INI. Il est plus courant de stocker les paramètres dans un fichier de configuration basé sur XML ou dans le registre. Cependant, si votre logiciel partage des paramètres avec une application héritée, il peut être plus facile d'utiliser son fichier de configuration, plutôt que de dupliquer les informations ailleurs.
Le framework .NET ne prend pas directement en charge l'utilisation des fichiers INI. Cependant, vous pouvez utiliser les fonctions de l'API Windows avec Platform Invocation Services (P / Invoke) pour écrire et lire à partir des fichiers. Dans ce lien, nous créons une classe qui représente les fichiers INI et utilise les fonctions de l'API Windows pour les manipuler. Veuillez passer par le lien suivant.
Lecture et écriture de fichiers INI
la source
Si vous voulez juste un simple lecteur sans sections et autres DLL, voici une solution simple:
Exemple d'utilisation:
Pendant ce temps, configurez le contenu du fichier (comme vous le voyez, prend en charge le symbole # pour le commentaire de ligne):
la source
Essayez cette méthode:
Il crée le dictionnaire où la clé est "-". Vous pouvez le charger comme ceci:
la source
PeanutButter.INI est une classe empaquetée Nuget pour la manipulation de fichiers INI. Il prend en charge la lecture / écriture, y compris les commentaires - vos commentaires sont conservés lors de l'écriture. Il semble être relativement populaire, testé et facile à utiliser. C'est aussi totalement gratuit et open-source.
Avertissement: je suis l'auteur de PeanutButter.INI.
la source
Je suis en retard pour rejoindre le parti, mais j'ai eu le même problème aujourd'hui et j'ai écrit l'implémentation suivante:
Il faut noter que cette implémentation ne gère pas les sections ou propriétés qui ne sont pas trouvées. Pour ce faire, vous devez étendre la
Dictionary<,>
classe-pour gérer les clés non trouvées.Pour sérialiser une instance de
Dictionary<string, Dictionary<string, string>>
en un.ini
-file, j'utilise le code suivant:la source
Un analyseur Ini est disponible dans CommonLibrary.NET
Cela a diverses surcharges très pratiques pour obtenir des sections / valeurs et est très léger.
la source
Voici ma propre version, utilisant des expressions régulières. Ce code suppose que chaque nom de section est unique - si ce n'est pas le cas - il est logique de remplacer Dictionary par List. Cette fonction prend en charge les commentaires de fichiers .ini, en commençant par ';' personnage. La section démarre normalement [section], et les paires valeur / clé viennent également normalement "clé = valeur". Même hypothèse que pour les sections - le nom de la clé est unique.
la source
Voici ma classe, fonctionne comme un charme:
}
L'utilisation est évitée car c'est une classe statique, il suffit d'appeler IniFileManager.IniWriteValue pour lire une section ou IniFileManager.IniReadValue pour lire une section.
la source
Vous devez lire et écrire des données à partir de fichiers xml car vous pouvez enregistrer un objet entier en xml et vous pouvez également remplir un objet à partir d'un xml enregistré. Il vaut mieux manipuler des objets facilement.
Voici comment procéder: Écrire des données d'objet dans un fichier XML: https://msdn.microsoft.com/en-us/library/ms172873.aspx Lire des données d'objet à partir d'un fichier XML: https://msdn.microsoft. com / fr-fr / library / ms172872.aspx
la source