read net leer example create configuracion change archivo c# .net ini

c# - example - leer archivo ini vb net



Leer/escribir un archivo INI (17)

Prefacio

En primer lugar, lea esta publicación del blog de MSDN sobre las limitaciones de los archivos INI . Si se adapta a sus necesidades, siga leyendo.

Esta es una implementación concisa que escribí, utilizando la versión original de Windows P / Invoke, por lo que es compatible con todas las versiones de Windows con .NET instalado (es decir, Windows 98 - Windows 10). Por la presente, lo libero al dominio público. Usted es libre de usarlo comercialmente sin atribución.

La pequeña clase

Agregue una nueva clase llamada IniFile.cs a su proyecto:

using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Text; // Change this to match your program''s normal namespace namespace MyProg { class IniFile // revision 11 { string Path; string EXE = Assembly.GetExecutingAssembly().GetName().Name; [DllImport("kernel32", CharSet = CharSet.Unicode)] static extern long WritePrivateProfileString(string Section, string Key, string Value, string FilePath); [DllImport("kernel32", CharSet = CharSet.Unicode)] static extern int GetPrivateProfileString(string Section, string Key, string Default, StringBuilder RetVal, int Size, string FilePath); public IniFile(string IniPath = null) { Path = new FileInfo(IniPath ?? EXE + ".ini").FullName.ToString(); } public string Read(string Key, string Section = null) { var RetVal = new StringBuilder(255); GetPrivateProfileString(Section ?? EXE, Key, "", RetVal, 255, Path); return RetVal.ToString(); } public void Write(string Key, string Value, string Section = null) { WritePrivateProfileString(Section ?? EXE, Key, Value, Path); } public void DeleteKey(string Key, string Section = null) { Write(Key, null, Section ?? EXE); } public void DeleteSection(string Section = null) { Write(null, null, Section ?? EXE); } public bool KeyExists(string Key, string Section = null) { return Read(Key, Section).Length > 0; } } }

Cómo usarlo

Abra el archivo INI de una de las 3 formas siguientes:

// Creates or loads an INI file in the same directory as your executable // named EXE.ini (where EXE is the name of your executable) var MyIni = new IniFile(); // Or specify a specific name in the current dir var MyIni = new IniFile("Settings.ini"); // Or specify a specific name in a specific dir var MyIni = new IniFile(@"C:/Settings.ini");

Puedes escribir algunos valores así:

MyIni.Write("DefaultVolume", "100"); MyIni.Write("HomePage", "http://www.google.com");

Para crear un archivo como este:

[MyProg] DefaultVolume=100 HomePage=http://www.google.com

Para leer los valores fuera del archivo INI:

var DefaultVolume = IniFile.Read("DefaultVolume"); var HomePage = IniFile.Read("HomePage");

Opcionalmente, puede configurar la [Section] :

MyIni.Write("DefaultVolume", "100", "Audio"); MyIni.Write("HomePage", "http://www.google.com", "Web");

Para crear un archivo como este:

[Audio] DefaultVolume=100 [Web] HomePage=http://www.google.com

También puede comprobar la existencia de una clave así:

if(!MyIni.KeyExists("DefaultVolume", "Audio")) { MyIni.Write("DefaultVolume", "100", "Audio"); }

Puedes borrar una clave así:

MyIni.DeleteKey("DefaultVolume", "Audio");

También puede eliminar una sección completa (incluyendo todas las claves) así:

MyIni.DeleteSection("Web");

Por favor, siéntase libre de comentar con cualquier mejora!

¿Hay alguna clase en el marco .NET que pueda leer / escribir archivos .ini estándar?

[Section] <keyname>=<value> ...

Delphi tiene el componente TIniFile y quiero saber si hay algo similar para C #?


Aquí está mi clase, funciona como un amuleto:

public static class IniFileManager { [DllImport("kernel32")] private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); [DllImport("kernel32")] private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); [DllImport("kernel32.dll")] private static extern int GetPrivateProfileSection(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 Name public static void IniWriteValue(string sPath,string Section, string Key, string Value) { 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> public static string IniReadValue(string sPath,string Section, string Key) { StringBuilder temp = new StringBuilder(255); int i = GetPrivateProfileString(Section, Key, "", temp, 255, sPath); return temp.ToString(); }

}

El uso es obvio, ya que es una clase estática, solo llame a IniFileManager.IniWriteValue para leer una sección o IniFileManager.IniReadValue para leer una sección.


Aquí está mi propia versión, usando expresiones regulares. Este código asume que cada nombre de sección es único; si esto no es cierto, tiene sentido reemplazar Diccionario por Lista. Esta función admite el comentario de archivos .ini, comenzando desde '';'' personaje. La sección comienza normalmente [sección], y los pares de valores clave también vienen normalmente "clave = valor". El mismo supuesto que para las secciones: el nombre de la clave es único.

/// <summary> /// Loads .ini file into dictionary. /// </summary> public static Dictionary<String, Dictionary<String, String>> loadIni(String file) { Dictionary<String, Dictionary<String, String>> d = new Dictionary<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 section foreach (Match m in Regex.Matches(ini, "(^|[/r/n])//[([^/r/n]*)//][/r/n]+(.*?)(//[([^/r/n]*)//][/r/n]+|$)", RegexOptions.Singleline)) { String sectionName = m.Groups[2].Value; Dictionary<String, String> lines = new Dictionary<String, String>(); // Pick up "key = value" kind of syntax. foreach (Match l in Regex.Matches(ini, @"^/s*(.*?)/s*=/s*(.*?)/s*$", RegexOptions.Multiline)) { String key = l.Groups[1].Value; String value = 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; }



El código en la respuesta de la junta es inspirador.

Desafortunadamente, cambia el carácter de las claves y no maneja los comentarios. Así que escribí algo que debería ser lo suficientemente robusto para leer (solo) archivos INI muy sucios y permitir recuperar claves como están.

Utiliza algo de LINQ, un diccionario de cadenas anidado que no distingue entre mayúsculas y minúsculas para almacenar secciones, claves y valores, y leer el archivo de una sola vez.

using System; using System.Collections.Generic; using System.IO; using System.Linq; class IniReader { Dictionary<string, Dictionary<string, string>> ini = new Dictionary<string, Dictionary<string, string>>(StringComparer.InvariantCultureIgnoreCase); public IniReader(string file) { var txt = File.ReadAllText(file); Dictionary<string, string> currentSection = new Dictionary<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 = new Dictionary<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); } } public string GetValue(string key) { return GetValue(key, "", ""); } public string GetValue(string key, string section) { return GetValue(key, section, ""); } public string GetValue(string key, string section, string @default) { if (!ini.ContainsKey(section)) return @default; if (!ini[section].ContainsKey(key)) return @default; return ini[section][key]; } public string[] GetKeys(string section) { if (!ini.ContainsKey(section)) return new string[0]; return ini[section].Keys.ToArray(); } public string[] GetSections() { return ini.Keys.Where(t => t != "").ToArray(); } }


Encontré esta implementación simple:

http://bytes.com/topic/net/insights/797169-reading-parsing-ini-file-c

Funciona bien para lo que necesito.

Así es como lo usas:

public class TestParser { public static void Main() { IniParser parser = new IniParser(@"C:/test.ini"); String newMessage; newMessage = parser.GetSetting("appsettings", "msgpart1"); newMessage += parser.GetSetting("appsettings", "msgpart2"); newMessage += parser.GetSetting("punctuation", "ex"); //Returns "Hello World!" Console.WriteLine(newMessage); Console.ReadLine(); } }

Aquí está el código:

using System; using System.IO; using System.Collections; public class IniParser { private Hashtable keyPairs = new Hashtable(); private String iniFilePath; private struct SectionPair { public String Section; public String Key; } /// <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> public IniParser(String iniPath) { TextReader iniFile = null; String strLine = null; String currentRoot = null; String[] keyPair = null; iniFilePath = iniPath; if (File.Exists(iniPath)) { try { iniFile = new StreamReader(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(new char[] { ''='' }, 2); SectionPair sectionPair; String value = 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(); } } else throw new FileNotFoundException("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> public String GetSetting(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> public String[] EnumSection(String sectionName) { ArrayList tmpArray = new ArrayList(); 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> public void AddSetting(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> public void AddSetting(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> public void DeleteSetting(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> public void SaveSettings(String newFilePath) { ArrayList sections = new ArrayList(); 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 = new StreamWriter(newFilePath); tw.Write(strToSave); tw.Close(); } catch (Exception ex) { throw ex; } } /// <summary> /// Save settings back to ini file. /// </summary> public void SaveSettings() { SaveSettings(iniFilePath); } }


Este artículo en CodeProject " Una clase de manejo de archivos INI usando C # " debería ayudar.

El autor creó una clase C # "Ini" que expone dos funciones de KERNEL32.dll. Estas funciones son: WritePrivateProfileString y GetPrivateProfileString . Necesitará dos espacios de nombres: System.Runtime.InteropServices y System.Text .

Pasos para utilizar la clase Ini.

En la definición del espacio de nombres de su proyecto agregue

using INI;

Crea un archivo INIF como este

INIFile ini = new INIFile("C://test.ini");

Use IniWriteValue para escribir un nuevo valor para una clave específica en una sección o use IniReadValue para leer un valor DE una clave en una Sección específica.

Nota: si comienza de cero, puede leer este artículo de MSDN : Cómo agregar archivos de configuración de la aplicación a los proyectos de C # . Es una mejor manera de configurar tu aplicación.


Hay un analizador Ini disponible en CommonLibrary.NET

Esto tiene varias sobrecargas muy convenientes para obtener secciones / valores y es muy ligero.


Llego tarde a la fiesta, pero hoy tuve el mismo problema y escribí la siguiente implementación:

using System.Text.RegularExpressions; static bool match(this string str, string pat, out Match m) => (m = Regex.Match(str, pat, RegexOptions.IgnoreCase)).Success; static void Main() { Dictionary<string, Dictionary<string, string>> ini = new Dictionary<string, Dictionary<string, string>>(); string section = ""; foreach (string line in File.ReadAllLines(.........)) // read from file { string ln = (line.Contains(''#'') ? line.Remove(line.IndexOf(''#'')) : line).Trim(); if (ln.match(@"^[ /t]*/[(?<sec>[/w/-]+)/]", out Match m)) section = m.Groups["sec"].ToString(); else if (ln.match(@"^[ /t]*(?<prop>[/w/-]+)/=(?<val>.*)", out m)) { if (!ini.ContainsKey(section)) ini[section] = new Dictionary<string, string>(); ini[section][m.Groups["prop"].ToString()] = m.Groups["val"].ToString(); } } // access the ini file as follows: string content = ini["section"]["property"]; }

Se debe tener en cuenta que esta implementación no maneja secciones o propiedades que no se encuentran. Para lograr esto, debe extender el Dictionary<,> -clase para manejar claves no encontradas.

Para serializar una instancia de Dictionary<string, Dictionary<string, string>> a un archivo .ini , uso el siguiente código:

string targetpath = .........; Dictionary<string, Dictionary<string, string>> ini = ........; StringBuilder sb = new StringBuilder(); 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());


Los creadores de .NET Framework quieren que uses archivos de configuración basados ​​en XML, en lugar de archivos INI. Entonces no, no hay un mecanismo incorporado para leerlos.

Sin embargo, hay soluciones de terceros disponibles.


Por lo general, cuando crea aplicaciones utilizando C # y .NET framework, no utilizará archivos INI. Es más común almacenar configuraciones en un archivo de configuración basado en XML o en el registro. Sin embargo, si su software comparte la configuración con una aplicación heredada, puede ser más fácil usar su archivo de configuración, en lugar de duplicar la información en otro lugar.

.NET Framework no admite el uso de archivos INI directamente. Sin embargo, puede usar las funciones de la API de Windows con Platform Invocation Services (P / Invoke) para escribir y leer desde los archivos. En este enlace creamos una clase que representa los archivos INI y utiliza las funciones de la API de Windows para manipularlos. Por favor, vaya a través del siguiente enlace.

Leer y escribir archivos INI


Prueba este método:

public static Dictionary<string, string> ParseIniDataWithSections(string[] iniData) { var dict = new Dictionary<string, string>(); var rows = iniData.Where(t => !String.IsNullOrEmpty(t.Trim()) && !t.StartsWith(";") && (t.Contains(''['') || t.Contains(''=''))); if (rows == null || rows.Count() == 0) return dict; string section = ""; foreach (string row in rows) { string rw = row.TrimStart(); if (rw.StartsWith("[")) section = rw.TrimStart(''['').TrimEnd('']''); else { int index = rw.IndexOf(''=''); dict[section + "-" + rw.Substring(0, index).Trim()] = rw.Substring(index+1).Trim().Trim(''"''); } } return dict; }

Crea el diccionario donde la clave es "-". Puedes cargarlo así:

var dict = ParseIniDataWithSections(File.ReadAllLines(fileName));


Puede usar SharpConfig para leer archivos .cfg y / o .ini. Es una biblioteca de configuración fácil de usar para .NET.


Quiero presentar una biblioteca IniParser que he creado completamente en c #, por lo que no contiene dependencias en ningún sistema operativo, lo que la hace compatible con Mono. Fuente abierta con licencia MIT, por lo que puede utilizarse en cualquier código.

Puede consultar la fuente en GitHub , y también está disponible como un paquete NuGet

Es muy configurable y realmente fácil de usar .

Lo siento por el desvergonzado enchufe, pero espero que pueda ser de ayuda para cualquiera que vuelva a visitar esta respuesta.


Si desea un simple lector sin secciones y cualquier otra DLL, aquí tiene una solución simple:

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Tool { public class Config { Dictionary <string, string> values; public Config (string path) { values = File.ReadLines(path) .Where(line => (!String.IsNullOrWhiteSpace(line) && !line.StartsWith("#"))) .Select(line => line.Split(new char[] { ''='' }, 2, 0)) .ToDictionary(parts => parts[0].Trim(), parts => parts.Length>1?parts[1].Trim():null); } public string Value (string name, string value=null) { if (values!=null && values.ContainsKey(name)) { return values[name]; } return value; } } }

Muestra de uso

file = new Tool.Config (Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "//config.ini"); command = file.Value ("command"); action = file.Value ("action"); string value; //second parameter is default value if no key found with this name value = file.Value("debug","true"); this.debug = (value.ToLower()=="true" || value== "1"); value = file.Value("plain", "false"); this.plain = (value.ToLower() == "true" || value == "1");

Mientras tanto, el contenido del archivo de configuración (como ve es compatible con el símbolo # para el comentario de la línea):

#command to run command = php #default script action = index.php #debug mode #debug = true #plain text mode #plain = false #icon = favico.ico


Si solo necesita acceso de lectura y no acceso de escritura y está utilizando Microsoft.Extensions.Confiuration (viene incluido de forma predeterminada con ASP.NET Core pero también funciona con programas normales) puede usar el paquete NuGet Microsoft.Extensions.Configuration.Ini para importar archivos ini a sus ajustes de configuración.

public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddIniFile("SomeConfig.ini", optional: false); Configuration = builder.Build(); }


PeanutButter.INI es una clase empaquetada con Nuget para la manipulación de archivos INI. Admite lectura / escritura, incluidos los comentarios: sus comentarios se conservan en escritura. Parece ser bastante popular, está probado y es fácil de usar. También es totalmente gratuito y de código abierto.

Descargo de responsabilidad: Soy el autor de PeanutButter.INI.