将密钥写入并更新到ini文件c#

将密钥写入并更新到ini文件c#,c#,C#,我想写一些设置到ini文件与此代码,搜索找到关键和更新它,如果找不到关键添加到文件。但它显示了这个错误: “对象引用未设置为对象的实例。” 我尝试以下代码: internal class IniData { public string Key; public string Value; } internal class IniSection : Dictionary<string, IniData> {

我想写一些设置到ini文件与此代码,搜索找到关键和更新它,如果找不到关键添加到文件。但它显示了这个错误: “对象引用未设置为对象的实例。” 我尝试以下代码:

    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();
    }
}