RemObjects possui uma biblioteca Delphi Prism chamada ShineOn que envia uma classe de arquivo INI semelhante. Mas você precisa do Delphi Prism para compilá-lo para .NET a partir da fonte, pois ainda não há um assembly compilado disponível. code.remobjects.com/p/shineon
Lex Li
1
Tem o mesmo problema e fiz a minha própria biblioteca para analisar arquivos ini: github.com/rickyah/ini-parser Espero que ajude
Os criadores da estrutura .NET desejam que você use arquivos de configuração baseados em XML, em vez de arquivos INI. Portanto, não, não há mecanismo interno para lê-los.
Existem soluções de terceiros disponíveis, no entanto.
Embora seja verdade que os arquivos de configuração XML sejam o caminho a seguir, isso ainda não é uma resposta para a pergunta ou é o VLQ apenas para link.
Danny Beckett
6
@aloneguid Eu diria que o grande conjunto de recursos disponíveis realmente contribuiu para os arquivos de configuração do .NET e acabou sendo um gigante estranho com muita magia neles. Eles se tornaram "código no arquivo de configuração" e isso gera muita complexidade, comportamentos estranhos e dificulta o gerenciamento de configurações. (Estou olhando para você, "provedores" de banco de dados e cadeias de conexão.) Portanto, os arquivos INI também são geralmente melhores para edição não manual também.
jpmc26
1
eu gosto do método antigo (P / Inovke) e você pode usar o unicode com o método antigo como este: File.WriteAllBytes (path, new byte [] {0xFF, 0xFE});
sailfish009
2
Bom pacote, mas poderia ser melhor. Ele não pode analisar um valor que contém '=' Ou '\ n' completamente
Ahmad Behjati
211
Prefácio
Em primeiro lugar, leia esta postagem do blog do MSDN sobre as limitações dos arquivos INI . Se atender às suas necessidades, continue lendo.
Esta é uma implementação concisa que escrevi, utilizando o Windows P / Invoke original, por isso é suportada por todas as versões do Windows com .NET instaladas (por exemplo, Windows 98 - Windows 10). Por meio deste, libero-o para o domínio público - você pode usá-lo comercialmente sem atribuição.
A pequena classe
Adicione uma nova classe chamada IniFile.csao seu projeto:
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;}}}
Como usá-lo
Abra o arquivo INI de uma das 3 maneiras a seguir:
// 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");
Estou um pouco atrasado, mas falta o GetSections()método.
stil
2
Talvez um padrão mais tradicional seja o arquivo .ini por aplicativo (não por assembly) Path.GetFullPath(IniPath ?? Path.ChangeExtension(Application.ExecutablePath, ".ini")).
Eugene Ryabtsev
3
Muito bom ! Colocá-lo no github?
Emrys Myrooin
2
@danny Beckett, muito bem feito. Isso é quase exatamente igual ao que eu usei nos últimos anos do .Net. Atualizado do código antigo anos atrás.
Damian
10
Antigo agora, e por mais que eu respeite Raymond Chen, muitas das limitações desse artigo eram limitações da biblioteca INI específica no Windows, e não o formato INI em si. Outros, como permissões granulares, podem ser facilmente evitados por meio de vários arquivos. Uma biblioteca oficial e modernizada do INI seria muito bem-vinda até hoje.
O autor criou uma classe C # "Ini", que expõe duas funções do KERNEL32.dll. Essas funções são: WritePrivateProfileStringe GetPrivateProfileString. Você precisará de dois espaços para nome: System.Runtime.InteropServicese System.Text.
Etapas para usar a classe Ini
Na definição do namespace do seu projeto, inclua
using INI;
Crie um INIFile como este
INIFile ini =newINIFile("C:\\test.ini");
Use IniWriteValuepara escrever um novo valor em uma chave específica em uma seção ou use IniReadValuepara ler um valor de uma chave em uma Seção específica.
Eu usei essa abordagem por algum tempo, mas os aprimoramentos de segurança iniciados no Win7 praticamente acabaram com isso para mim. Você ainda pode usar essa abordagem, mas armazenará o .ini no ProgramData e o aplicativo lerá / gravará lá.
Jess
Não salve os arquivos ini de configuração do aplicativo no ProgramData. Eles não pertencem ao Registry ou ProgramData. Os arquivos de configuração devem estar nas pastas 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 para compensar acima do voto negativo. Do que você realmente reclama? Ele disse que encontrou. Você o recusou por não encontrar um com acessadores genéricos e uso do construtor de strings?
Tormod 15/09
1
@ Tormod: Gostaria de poder rebaixar o comentário. É um fórum técnico quando votamos em soluções, não na intenção (obviamente positiva). Se uma solução publicada pelo próprio Knuth tivesse falhas, ela deveria - e deveria - ser apontada. Não importa se a solução foi encontrada ou escrita pelo pôster.
precisa
7
Eu acho que você estica a definição de "falha". Se a solução não enfatizar suas sensibilidades, simplesmente não faça votos positivos. Acabei de deixar uma nota dizendo que eu já neguei o voto negativo para que os outros 7 caras que votaram no meu comentário não fizessem isso sozinhos.
Tormod 21/02
21
O código na resposta do joerage é inspirador.
Infelizmente, ele altera as letras maiúsculas e minúsculas dos caracteres e não trata dos comentários. Então, eu escrevi algo que deveria ser robusto o suficiente para ler (apenas) arquivos INI muito sujos e permitir recuperar as chaves como estão.
Ele usa algum LINQ, um dicionário de strings que não faz distinção entre maiúsculas e minúsculas para armazenar seções, chaves e valores e ler o arquivo de uma só vez.
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();}}
e obrigado por não colocar isso catch (Exception ex) { throw ex; }lá #
Mark Schultheiss
1
Boa! Pelo menos algumas mudanças são necessárias para funcionar melhor. Linha 16: ini [""] = currentSection; Para: // ini [""] = currentSection; Isso deve ser removido, pois sempre que o primeiro elemento [0] for um segmento vazio devido a essa inicialização. Linha 36: currentSection [line.Substring (0, idx)] = line.Substring (idx + 1); Para: currentSection [line.Substring (0, idx) .Trim ()] = line.Substring (idx + 1) .Trim (); A chave e os valores devem ser aparados independentemente, não apenas na linha Aparar. Nos arquivos de configuração do INI, geralmente os que adicionam pares K-> V tendem a alinhar esses iguais dentro das seções. Obrigado!
LXSoft 4/18
Já faz um bom tempo. Muito obrigado por suas sugestões. Todos eles fazem sentido e merecem esse código para uma boa atualização.
Larry
13
Quero apresentar uma biblioteca IniParser que criei completamente em c #, para que não contenha dependências em nenhum sistema operacional, o que o torna compatível com Mono. Código aberto com licença MIT - para que possa ser usado em qualquer código.
Se você precisar apenas de acesso de leitura e não de gravação, e estiver usando o Microsoft.Extensions.Confiuration(vem incluído por padrão no ASP.NET Core, mas também trabalha com programas regulares), você pode usar o pacote NuGet Microsoft.Extensions.Configuration.Inipara importar arquivos ini para as definições de configuração.
Só para acrescentar que, em seguida, obter as chaves comConfiguration["keyname"]
kofifus
@ Scott, o problema que estou tendo é por qualquer motivo que o IIS não o reconheça quando o aplicativo está sendo executado. está implantado e lá, mas não está sendo consumido. O HTTP 500.30 retornou e o log do IIS App diz "o arquivo de configuração não foi encontrado e não é opcional".
one.beat.consumer
3
Normalmente, quando você cria aplicativos usando C # e a estrutura .NET, não usa arquivos INI. É mais comum armazenar configurações em um arquivo de configuração baseado em XML ou no registro. No entanto, se o seu software compartilhar configurações com um aplicativo herdado, poderá ser mais fácil usar o arquivo de configuração, em vez de duplicar as informações em outro local.
A estrutura .NET não oferece suporte ao uso de arquivos INI diretamente. No entanto, você pode usar as funções da API do Windows com os Serviços de Invocação de Plataforma (P / Invoke) para gravar e ler os arquivos. Neste link, criamos uma classe que representa arquivos INI e usa funções da API do Windows para manipulá-los. Por favor, acesse o seguinte link.
Fique fora do registro! Os dados de configuração do aplicativo não devem ser salvos no Registro.
deegee
3
Se você quer apenas um leitor simples, sem seções e quaisquer outras DLLs, aqui é uma solução simples:
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;}}}
Amostra de uso:
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");
Enquanto isso, configure o conteúdo do arquivo (como você vê no símbolo # dos comentários da linha):
#command to run
command = php
#default script
action = index.php
#debug mode#debug = true#plain text mode#plain = false#icon = favico.ico
PeanutButter.INI é uma classe empacotada em Nuget para manipulação de arquivos INI. Ele suporta leitura / gravação, incluindo comentários - seus comentários são preservados na gravação. Parece ser razoavelmente popular, testado e fácil de usar. Também é totalmente gratuito e de código aberto.
Estou atrasado para ingressar na festa, mas tive o mesmo problema hoje e escrevi a seguinte implementação:
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"];}
Deve-se notar que esta implementação não trata de seções ou propriedades que não são encontradas. Para conseguir isso, você deve estender a Dictionary<,>classe-para manipular chaves não encontradas.
Para serializar uma instância de Dictionary<string, Dictionary<string, string>>para um .iniarquivo, use o seguinte código:
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());
Caso não seja óbvio olhar para o nível superior da biblioteca (não era óbvio para mim!), A classe IniDcoument e outros estão no ComLib.IO.
Tim Keating
2
Para quem olha para essa rota, o CommonLibrary.NET parece não seguir as convenções .INI. Ele usa dois-pontos ":" como delimitador, em vez de sinal de igual, e não processa comentários (iniciar uma linha com um sinal de ponto-e-vírgula ou libra fará com que a análise falhe).
jmmr
2
Aqui está minha própria versão, usando expressões regulares. Esse código pressupõe que cada nome de seção seja exclusivo - se, no entanto, isso não for verdade - faz sentido substituir Dicionário por Lista. Esta função suporta comentários de arquivo .ini, iniciando em ';' personagem. Seção começa normalmente [seção], e pares de valores-chave também vêm normalmente "chave = valor". A mesma suposição das seções - o nome da chave é único.
/// <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;}
Essa função não funciona, para mim: esquece uma seção em duas. Eu tentei com e sem linhas vazias antes de [Seção].
iksess
você pode copiar exemplo do seu. ini que não funciona?
TarmoPikaro
-3
Aqui está a minha turma, funciona como um encanto:
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();}
}
O uso é óbvio, pois é uma classe estática, basta chamar IniFileManager.IniWriteValue para ler uma seção ou IniFileManager.IniReadValue para ler uma seção.
Essa abordagem já foi mostrada e explicada em outra resposta . O que sua resposta acrescenta que não é abordada por essa?
Palec
Observe que ele funciona apenas se o arquivo .ini estiver salvo no UNICODE (16bit LE). Use o Notepad ++ para converter o texto em unicode, porque se você o salvar em UTF-8 não funcionará. Também ANSI é aceitável, mas você não pode ler letras acentuadas
user2991288
-6
Você deve ler e gravar dados de arquivos xml, pois pode salvar um objeto inteiro em xml e também pode preencher um objeto a partir de um xml salvo. É melhor um fácil de manipular objetos.
Os links para recursos externos são incentivados, mas adicione contexto ao redor do link para que seus colegas usuários tenham uma idéia do que é e por que está lá. Sempre cite a parte mais relevante de um link importante, caso o site de destino esteja inacessível ou fique permanentemente offline.
davejal 13/01
Acredito que os títulos dos links sejam muito claros sobre suas referências / contexto. Se você acha que isso não é suficiente, fique à vontade para editá-lo.
Respostas:
Os criadores da estrutura .NET desejam que você use arquivos de configuração baseados em XML, em vez de arquivos INI. Portanto, não, não há mecanismo interno para lê-los.
Existem soluções de terceiros disponíveis, no entanto.
fonte
Prefácio
Em primeiro lugar, leia esta postagem do blog do MSDN sobre as limitações dos arquivos INI . Se atender às suas necessidades, continue lendo.
Esta é uma implementação concisa que escrevi, utilizando o Windows P / Invoke original, por isso é suportada por todas as versões do Windows com .NET instaladas (por exemplo, Windows 98 - Windows 10). Por meio deste, libero-o para o domínio público - você pode usá-lo comercialmente sem atribuição.
A pequena classe
Adicione uma nova classe chamada
IniFile.cs
ao seu projeto:Como usá-lo
Abra o arquivo INI de uma das 3 maneiras a seguir:
Você pode escrever alguns valores assim:
Para criar um arquivo como este:
Para ler os valores do arquivo INI:
Opcionalmente, você pode definir
[Section]
:Para criar um arquivo como este:
Você também pode verificar a existência de uma chave como esta:
Você pode excluir uma chave da seguinte maneira:
Você também pode excluir uma seção inteira (incluindo todas as chaves) da seguinte maneira:
Por favor, sinta-se livre para comentar com quaisquer melhorias!
fonte
GetSections()
método.Path.GetFullPath(IniPath ?? Path.ChangeExtension(Application.ExecutablePath, ".ini"))
.Este artigo no CodeProject " Uma classe de manipulação de arquivos INI usando C # " deve ajudar.
O autor criou uma classe C # "Ini", que expõe duas funções do KERNEL32.dll. Essas funções são:
WritePrivateProfileString
eGetPrivateProfileString
. Você precisará de dois espaços para nome:System.Runtime.InteropServices
eSystem.Text
.Etapas para usar a classe Ini
Na definição do namespace do seu projeto, inclua
Crie um INIFile como este
Use
IniWriteValue
para escrever um novo valor em uma chave específica em uma seção ou useIniReadValue
para ler um valor de uma chave em uma Seção específica.Nota: se você está começando do zero, pode ler este artigo do MSDN : Como: Adicionar arquivos de configuração de aplicativos a projetos C # . É uma maneira melhor de configurar seu aplicativo.
fonte
Eu encontrei esta implementação simples:
http://bytes.com/topic/net/insights/797169-reading-parsing-ini-file-c
Funciona bem para o que eu preciso.
Aqui está como você o usa:
Aqui está o código:
fonte
O código na resposta do joerage é inspirador.
Infelizmente, ele altera as letras maiúsculas e minúsculas dos caracteres e não trata dos comentários. Então, eu escrevi algo que deveria ser robusto o suficiente para ler (apenas) arquivos INI muito sujos e permitir recuperar as chaves como estão.
Ele usa algum LINQ, um dicionário de strings que não faz distinção entre maiúsculas e minúsculas para armazenar seções, chaves e valores e ler o arquivo de uma só vez.
fonte
catch (Exception ex) { throw ex; }
lá #Quero apresentar uma biblioteca IniParser que criei completamente em c #, para que não contenha dependências em nenhum sistema operacional, o que o torna compatível com Mono. Código aberto com licença MIT - para que possa ser usado em qualquer código.
Você pode verificar a fonte no GitHub , e também está disponível como um pacote NuGet
É altamente configurável e realmente simples de usar .
Desculpem o plugue descarado, mas espero que ajude quem estiver revisando esta resposta.
fonte
Se você precisar apenas de acesso de leitura e não de gravação, e estiver usando o
Microsoft.Extensions.Confiuration
(vem incluído por padrão no ASP.NET Core, mas também trabalha com programas regulares), você pode usar o pacote NuGetMicrosoft.Extensions.Configuration.Ini
para importar arquivos ini para as definições de configuração.fonte
Configuration["keyname"]
Normalmente, quando você cria aplicativos usando C # e a estrutura .NET, não usa arquivos INI. É mais comum armazenar configurações em um arquivo de configuração baseado em XML ou no registro. No entanto, se o seu software compartilhar configurações com um aplicativo herdado, poderá ser mais fácil usar o arquivo de configuração, em vez de duplicar as informações em outro local.
A estrutura .NET não oferece suporte ao uso de arquivos INI diretamente. No entanto, você pode usar as funções da API do Windows com os Serviços de Invocação de Plataforma (P / Invoke) para gravar e ler os arquivos. Neste link, criamos uma classe que representa arquivos INI e usa funções da API do Windows para manipulá-los. Por favor, acesse o seguinte link.
Lendo e gravando arquivos INI
fonte
Se você quer apenas um leitor simples, sem seções e quaisquer outras DLLs, aqui é uma solução simples:
Amostra de uso:
Enquanto isso, configure o conteúdo do arquivo (como você vê no símbolo # dos comentários da linha):
fonte
Tente este método:
Ele cria o dicionário onde a chave é "-". Você pode carregá-lo assim:
fonte
PeanutButter.INI é uma classe empacotada em Nuget para manipulação de arquivos INI. Ele suporta leitura / gravação, incluindo comentários - seus comentários são preservados na gravação. Parece ser razoavelmente popular, testado e fácil de usar. Também é totalmente gratuito e de código aberto.
Disclaimer: Eu sou o autor de PeanutButter.INI.
fonte
Estou atrasado para ingressar na festa, mas tive o mesmo problema hoje e escrevi a seguinte implementação:
Deve-se notar que esta implementação não trata de seções ou propriedades que não são encontradas. Para conseguir isso, você deve estender a
Dictionary<,>
classe-para manipular chaves não encontradas.Para serializar uma instância de
Dictionary<string, Dictionary<string, string>>
para um.ini
arquivo, use o seguinte código:fonte
Há um Analisador Ini disponível no CommonLibrary.NET
Isso possui várias sobrecargas muito convenientes para obter seções / valores e é muito leve.
fonte
Aqui está minha própria versão, usando expressões regulares. Esse código pressupõe que cada nome de seção seja exclusivo - se, no entanto, isso não for verdade - faz sentido substituir Dicionário por Lista. Esta função suporta comentários de arquivo .ini, iniciando em ';' personagem. Seção começa normalmente [seção], e pares de valores-chave também vêm normalmente "chave = valor". A mesma suposição das seções - o nome da chave é único.
fonte
Aqui está a minha turma, funciona como um encanto:
}
O uso é óbvio, pois é uma classe estática, basta chamar IniFileManager.IniWriteValue para ler uma seção ou IniFileManager.IniReadValue para ler uma seção.
fonte
Você deve ler e gravar dados de arquivos xml, pois pode salvar um objeto inteiro em xml e também pode preencher um objeto a partir de um xml salvo. É melhor um fácil de manipular objetos.
Aqui está como fazer isso: Gravar dados do objeto em um arquivo XML: https://msdn.microsoft.com/en-us/library/ms172873.aspx Ler dados do objeto de um arquivo XML: https://msdn.microsoft. com / pt-br / library / ms172872.aspx
fonte