А почему ini? Это же устаревший формат. Можно легко заменить на XML и использовать сериализацию. А если бы писали на C#, то вообще можно было бы использовать встроеную функцию Application Settings...
Я у себя в одной тулзе использовал что-то типа этого:
C#
Код:
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace stream.status
{
[XmlRootAttribute("Config", Namespace = "")]
public class Config
{
private const string FileName = "streams.xml";
public bool Speech { get; set; }
public bool OnlineOnly { get; set; }
public int Interval { get; set; }
// список стримов
public readonly List<StreamInfo> Streams = new List<StreamInfo>();
private static XmlSerializer Serializer = new XmlSerializer(typeof(Config), /*extra types*/ new Type[] { typeof(StreamInfo) });
private static Config instance;
private Config() { }
/// <summary>
/// Creates empty config with default settings
/// </summary>
private static void Init()
{
using (var fs = new FileStream(FileName, FileMode.Create))
{
Serializer.Serialize(fs, new Config());
}
}
/// <summary>
/// Saves current settings to a file
/// </summary>
public void Save()
{
using (var fs = new FileStream(FileName, FileMode.Create))
{
Serializer.Serialize(fs, instance);
}
}
public static Config Instance
{
get
{
if (instance == null)
{
if (!File.Exists(FileName))
Init();
using (var fs = new FileStream(FileName, FileMode.Open))
{
instance = (Config)Serializer.Deserialize(fs);
}
}
return instance;
}
}
}
}
C++/CLI
Код:
#pragma once
using namespace System;
using namespace System::Collections::Generic;
using namespace System::IO;
using namespace System::Xml::Serialization;
public ref class StreamInfo
{
public:
StreamInfo() {}
[XmlAttribute]
Int32 TestValue;
};
[XmlRoot("Config", Namespace="")]
public ref class Config
{
// Methods
private:
Config()
{
Streams = gcnew List<StreamInfo^>();
}
static void Init()
{
FileStream ^ fs = nullptr;
try
{
fs = gcnew FileStream(FileName, FileMode::Create);
Config::Serializer->Serialize(fs, gcnew Config());
}
finally
{
if(fs != nullptr)
delete fs;
}
}
public:
void Save()
{
FileStream ^ fs = nullptr;
try
{
fs = gcnew FileStream(FileName, FileMode::Create);
Config::Serializer->Serialize(fs, Config::instance);
}
finally
{
if(fs != nullptr)
delete fs;
}
}
// Properties
public:
property static Config ^ Instance
{
Config ^ get()
{
if (Config::instance == nullptr)
{
if (!File::Exists(FileName))
{
Config::Init();
}
FileStream ^ fs = nullptr;
try
{
fs = gcnew FileStream(FileName, FileMode::Open);
Config::instance = (Config^)(Config::Serializer->Deserialize(fs));
}
finally
{
if(fs != nullptr)
delete fs;
}
}
return Config::instance;
}
}
property Int32 Interval
{
Int32 get()
{
return _interval;
}
void set(Int32 val)
{
_interval = val;
}
}
property Boolean OnlineOnly
{
Boolean get()
{
return _onlineOnly;
}
void set(Boolean val)
{
_onlineOnly = val;
}
}
property Boolean Speech
{
Boolean get()
{
return _speech;
}
void set(Boolean val)
{
_speech = val;
}
}
// Fields
private:
literal String ^ FileName = "streams.xml";
static Config ^ instance;
static initonly XmlSerializer ^ Serializer = gcnew XmlSerializer(Config::typeid, gcnew array<Type ^, 1> { StreamInfo::typeid });
Int32 _interval;
Boolean _onlineOnly;
Boolean _speech;
public:
initonly List<StreamInfo^> ^ Streams;
};
Использование:
Код:
var streamsCount = Config.Instance.Streams.Count;
...
useSpeechToolStripMenuItem.Checked = Config.Instance.Speech;
...
onlineOnlyToolStripMenuItem.Checked = Config.Instance.OnlineOnly;
...
timer1.Interval = Config.Instance.Interval;
...
Config.Instance.Interval = timer1.Interval;
Config.Instance.Save();
...
Config.Instance.Speech = useSpeechToolStripMenuItem.Checked;
Config.Instance.Save();
...
Config.Instance.OnlineOnly = onlineOnlyToolStripMenuItem.Checked;
Config.Instance.Save();
...
Config.Instance.Streams.Add(new StreamInfo(f.Id, f.StreamName, f.Type));
Config.Instance.Save();
на выходе получается вот такой XML файл:
Код:
<?xml version="1.0"?>
<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Streams>
<StreamInfo Id="1" Name="Stream 1" Type="Own3d" />
...
<StreamInfo Id="n" Name="Stream n" Type="Justin" />
</Streams>
<Speech>true</Speech>
<OnlineOnly>false</OnlineOnly>
<Interval>120000</Interval>
</Config>