将密钥写入并更新到ini文件c#
我想写一些设置到ini文件与此代码,搜索找到关键和更新它,如果找不到关键添加到文件。但它显示了这个错误: “对象引用未设置为对象的实例。” 我尝试以下代码:将密钥写入并更新到ini文件c#,c#,C#,我想写一些设置到ini文件与此代码,搜索找到关键和更新它,如果找不到关键添加到文件。但它显示了这个错误: “对象引用未设置为对象的实例。” 我尝试以下代码: internal class IniData { public string Key; public string Value; } internal class IniSection : Dictionary<string, IniData> {
internal class IniData
{
public string Key;
public string Value;
}
internal class IniSection : Dictionary<string, IniData>
{
public string Name { get; set; }
}
internal class IniFile : Dictionary<string, IniSection>
{
public string Path { get; set; }
}
public sealed class IniManager
{
private static readonly Dictionary<string, IniFile> IniFiles;
static IniManager()
{
IniFiles = new Dictionary<string, IniFile>();
}
public static void WriteIni(string fileName, string section, string key, string value)
{
/* Check if ini file exists in the ini collection */
var fileKey = fileName.ToLower();
if (!IniFiles.ContainsKey(fileKey))
{
if (!ImportIni(fileKey))
{
/* Add a new blank file */
var ini = new IniFile { Path = fileName };
IniFiles.Add(fileKey, ini);
}
}
/* Find section */
if (IniFiles[fileKey].ContainsKey(section.ToLower()))
{
/* Find key, if exists replace it */
if (IniFiles[fileKey][section.ToLower()].ContainsKey(key.ToLower()))
{
IniFiles[fileKey][section.ToLower()][key.ToLower()].Value = value;
return;
}
var data = new IniData { Key = key, Value = value };
IniFiles[fileKey][section.ToLower()].Add(key.ToLower(), data);
}
else
{
/* Create new ini section */
var sec = new IniSection { Name = section };
var data = new IniData { Key = key, Value = value };
sec.Add(key.ToLower(), data);
IniFiles[fileKey].Add(section.ToLower(), sec);
}
}
private static bool ImportIni(string fileName)
{
if (!File.Exists(fileName)) { return false; }
string[] data;
try
{
using (var stream = new FileStream(fileName, FileMode.Open))
{
using (var reader = new StreamReader(stream))
{
data = reader.ReadToEnd().Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
reader.Close();
}
stream.Close();
}
}
catch (Exception) { return false; }
if (data.Length == 0) { return false; }
var file = new IniFile { Path = fileName };
var section = new IniSection();
foreach (var s in data)
{
if (s.StartsWith("[") && s.EndsWith("]"))
{
/* Section header */
if (section.Count > 0)
{
/* Add current section */
file.Add(section.Name.ToLower(), section);
}
section = new IniSection { Name = s.Replace("[", null).Replace("]", null) };
continue;
}
/* Using current section, parse ini keys/values */
var iniData = ParseIni(s);
section.Add(iniData.Key.ToLower(), iniData);
}
if (section.Count > 0)
{
/* Add current section */
//@@@@@@@@@@@@@@@@@@Erorr : Object reference not set to an instance of an object.
file.Add(section.Name.ToLower(), section);
}
IniFiles.Add(fileName, file);
return true;
}
private static IniData ParseIni(string s)
{
var parts = s.Split('=');
return new IniData { Key = parts[0].Trim(), Value = parts.Length > 1 ? parts[1].Trim() : string.Empty };
}
}
private void button9_Click(object sender, EventArgs e)
{
IniManager.WriteIni("seting.ini", "Sec", "key", "value");
}
内部类数据
{
公共字符串密钥;
公共字符串值;
}
内部类:字典
{
公共字符串名称{get;set;}
}
内部类文件:字典
{
公共字符串路径{get;set;}
}
公共密封类管理器
{
私有静态只读字典文件;
静态管理器()
{
ini文件=新字典();
}
公共静态void WriteIni(字符串文件名、字符串节、字符串键、字符串值)
{
/*检查ini集合中是否存在ini文件*/
var fileKey=fileName.ToLower();
如果(!IniFiles.ContainsKey(fileKey))
{
如果(!ImportIni(fileKey))
{
/*添加新的空白文件*/
var ini=新的ini文件{Path=fileName};
添加(fileKey,ini);
}
}
/*查找部分*/
if(ini文件[fileKey].ContainsKey(section.ToLower()))
{
/*查找密钥,如果存在,请将其替换*/
if(ini文件[fileKey][section.ToLower()].ContainsKey(key.ToLower()))
{
IniFiles[fileKey][section.ToLower()][key.ToLower()].Value=Value;
返回;
}
var data=new-IniData{Key=Key,Value=Value};
ini文件[fileKey][section.ToLower()].Add(key.ToLower(),数据);
}
其他的
{
/*创建新的ini节*/
var sec=new-IniSection{Name=section};
var data=new-IniData{Key=Key,Value=Value};
添加(key.ToLower(),数据)一节;
IniFiles[fileKey].Add(section.ToLower(),sec);
}
}
私有静态bool ImportIni(字符串文件名)
{
如果(!File.Exists(fileName)){return false;}
字符串[]数据;
尝试
{
使用(var stream=newfilestream(文件名,FileMode.Open))
{
使用(变量读取器=新的流读取器(流))
{
data=reader.ReadToEnd().Split(新[]{'\r','\n'},StringSplitOptions.RemoveEmptyEntries);
reader.Close();
}
stream.Close();
}
}
catch(异常){return false;}
如果(data.Length==0){return false;}
var file=new-ini文件{Path=fileName};
var section=新的IniSection();
foreach(数据中的var s)
{
如果(s.StartsWith(“[”)&&s.EndsWith(“]))
{
/*节头*/
如果(section.Count>0)
{
/*添加当前节*/
file.Add(section.Name.ToLower(),section);
}
section=new-IniSection{Name=s.Replace(“[”,null).Replace(“]”,null)};
继续;
}
/*使用当前节,解析ini键/值*/
var-iniData=ParseIni(s);
添加(iniData.Key.ToLower(),iniData);
}
如果(section.Count>0)
{
/*添加当前节*/
//@@@@@@@@@@@@@@@@@@Erorr:对象引用未设置为对象的实例。
file.Add(section.Name.ToLower(),section);
}
添加(文件名,文件名);
返回true;
}
私有静态IniData ParseIni(字符串s)
{
var parts=s.Split('=');
返回新的IniData{Key=parts[0]。Trim(),Value=parts.Length>1?parts[1]。Trim():string.Empty};
}
}
私有无效按钮9_单击(对象发送者,事件参数e)
{
WriteIni(“seting.ini”、“Sec”、“key”、“value”);
}
这里的问题是,如果文件以键而不是节开始,则foreach
与if(s.StartsWith(“[”)&&s.EndsWith(“])
根本不匹配,因此从不设置节.Name
,因此在文件.Add(section.Name.ToLower(),section)中调用时为null
代码>
顺便说一句:您的代码似乎有很多缺陷,请尝试重新设计它,至少在ImportIni的主foreach
中,而不是自己实现它,您应该使用Windows提供的API函数。当然,如果您需要在Mono或Windows以外的其他平台上运行它,您需要返回到纯.NET实现,但即使如此,我可能会寻找现有的实现,而不是自己创建轮子
以下是API函数:
下面是一个使用它们的示例程序:
(点击F4并将以下两行粘贴到附加名称空间选项卡中):
然后试试这个程序:
void Main()
{
var ini = new IniFile(@"d:\temp\test.ini");
ini.WriteValue("Section", "Key", "Value");
ini.ReadValue("Section", "Key").Dump();
ini["Main", "Key2"] = "Test";
ini["Main", "Key2"].Dump();
}
[DllImport("kernel32.dll", CharSet=CharSet.Unicode)]
static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName,string lpDefault, StringBuilder lpReturnedString, uint nSize,string lpFileName);
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);
public class IniFile
{
const int MAX_SIZE = 1024;
private readonly string _FilePath;
public IniFile(string filePath)
{
if (filePath == null)
throw new ArgumentNullException("filePath");
_FilePath = filePath;
}
public string this[string section, string key]
{
get
{
return ReadValue(section, key);
}
set
{
WriteValue(section, key, value);
}
}
public string ReadValue(string section, string key, string defaultValue = null)
{
var result = new StringBuilder(MAX_SIZE);
if (GetPrivateProfileString(section, key, defaultValue ?? string.Empty, result, (uint)result.Capacity, _FilePath) > 0)
return result.ToString();
throw new Win32Exception();
}
public void WriteValue(string section, string key, string value)
{
if (!WritePrivateProfileString(section, key, value, _FilePath))
throw new Win32Exception();
}
}
这发生在哪一行?关于NullReferenceException
有一千万个问题。请阅读它们,试着理解发生了什么,调试你的程序并自己找到答案。提示:它是关于节的。Name
。使用INI文件似乎有点过时。为什么不简单地使用and呢?
void Main()
{
var ini = new IniFile(@"d:\temp\test.ini");
ini.WriteValue("Section", "Key", "Value");
ini.ReadValue("Section", "Key").Dump();
ini["Main", "Key2"] = "Test";
ini["Main", "Key2"].Dump();
}
[DllImport("kernel32.dll", CharSet=CharSet.Unicode)]
static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName,string lpDefault, StringBuilder lpReturnedString, uint nSize,string lpFileName);
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);
public class IniFile
{
const int MAX_SIZE = 1024;
private readonly string _FilePath;
public IniFile(string filePath)
{
if (filePath == null)
throw new ArgumentNullException("filePath");
_FilePath = filePath;
}
public string this[string section, string key]
{
get
{
return ReadValue(section, key);
}
set
{
WriteValue(section, key, value);
}
}
public string ReadValue(string section, string key, string defaultValue = null)
{
var result = new StringBuilder(MAX_SIZE);
if (GetPrivateProfileString(section, key, defaultValue ?? string.Empty, result, (uint)result.Capacity, _FilePath) > 0)
return result.ToString();
throw new Win32Exception();
}
public void WriteValue(string section, string key, string value)
{
if (!WritePrivateProfileString(section, key, value, _FilePath))
throw new Win32Exception();
}
}