存储在我的程序中使用的值列表的最佳方法是什么,并允许用户更改它们? XML文件或INI文件为什么?
如果您有更好的建议,欢迎您。
编辑:为了得到最合适的答案,这里有一些细节。但是,答案可以帮助其他用户,因为自定义详细信息仅作为注释编写。
我有一系列元素,每个元素都标有“true”或“false”值 在我的程序中,我只想使用列表中带有“true”值的元素。
我只能使用带有“True”元素的Enum,但我希望用户选择他想要的元素,将false更改为true,反之亦然。
但是,我不希望他在每次执行中选择所需的元素。这就是为什么我考虑使用一个可以根据用户优先权轻松改变的文件。
答案 0 :(得分:3)
我建议使用.NET默认方式,这肯定是XML。
使用XML,您可以获得优于INI格式的优势:
答案 1 :(得分:3)
在我看来,有很多选择,但如果没有经验,你应该尽可能地保持它。
一种方法是使用您可以使用项目本身生成的设置。
只需在解决方案资源管理器中点击Add > New Item
,即可将设置文件添加到项目中,然后选择Settings File
。
This是一篇有关向设置文件添加列表的有用文章。
在您的情况下,您还可以选择string
设置。只需使用以下内容将整数值保存到string
Properties.Settings.Default.SettingX = string.Join(",", array);
使用以下方法阅读它们:
string[] list = Properties.Settings.Default.SettingX.Split(',');
答案 2 :(得分:2)
答案 3 :(得分:2)
回答最佳问题可能是一笔巨大的交易。我认为这里有几个很好的解决方案是我的,希望它有所帮助。
实际上我在很多应用程序上工作,所有这些应用程序都需要由最终用户配置。 花了一段时间使用'xml'后,我改为使用“propertyName”=“value”的简单ini文件。
我写了一个简单的类来处理这类文件。用法很简单
Settings.ConfigProperties cfProps = new Settings.ConfigProperties("c:\\test.ini");
//if the file exists it will be read
//to update or insert new values
cfProps.UpdateValue("myNewProperty", "myValue");
//to get a stored value
String readValue = cfProps.ToString("myNewProperty");
//to permanently write changes to the ini file
cfProps.Save();
这是代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Settings
{
public class ConfigProperties
{
public class PropertyList<T> : List<ConfigProperty>
{
public ConfigProperty this[String propertyName]
{
get
{
ConfigProperty ret = null;
foreach (ConfigProperty cp in this)
{
if (cp.Name == propertyName)
{
ret = cp;
break;
}
}
return ret;
}
set
{
ConfigProperty ret = null;
foreach (ConfigProperty cp in this)
{
if (cp.Name == propertyName)
{
ret = cp;
break;
}
}
value = ret;
}
}
public PropertyList()
: base()
{
}
public void Add(String Name, String Value)
{
ConfigProperty cp = new ConfigProperty();
cp.Name = Name;
cp.Value = Value;
this.Add(cp);
}
}
public class ConfigProperty
{
public String Name { get; set; }
public String Value { get; set; }
public ConfigProperty()
{
Name = "newPropertyName_" + DateTime.Now.Ticks.ToString();
Value = "";
}
public ConfigProperty(String name, String value)
{
Name = name;
Value = value;
}
}
public String FileName { get; set; }
public PropertyList<ConfigProperty> CFCollection { get; private set; }
public ConfigProperties()
: this(AppDomain.CurrentDomain.BaseDirectory + "config.ini")
{
}
public ConfigProperties(String fileName)
{
CFCollection = new PropertyList<ConfigProperty>();
FileName = fileName;
if (fileName != null && File.Exists(fileName))
{
ReadFile();
}
}
private void ReadFile()
{
if (File.Exists(FileName))
{
CFCollection = new PropertyList<ConfigProperty>();
using (StreamReader sr = new StreamReader(FileName, Encoding.Default))
{
while (!sr.EndOfStream)
{
String line = sr.ReadLine();
if (!line.StartsWith("#"))
{
ConfigProperty cf = new ConfigProperty();
String tmp = "";
Char splitter = '=';
for (int i = 0; i < line.Length; i++)
{
if (line[i] != splitter)
{
tmp += ((Char)line[i]).ToString();
}
else
{
cf.Name = tmp;
tmp = "";
splitter = '\n';
}
}
cf.Value = tmp;
if (cf.Name.Length > 0)
{
CFCollection.Add(cf);
}
}
}
sr.Close();
}
}
}
private void SaveConfigProperty(ConfigProperty prop)
{
List<String> output = new List<String>();
if (File.Exists(FileName))
{
using (StreamReader sr = new StreamReader(FileName, Encoding.Default))
{
while (!sr.EndOfStream)
{
String line = sr.ReadLine();
if (line.StartsWith(prop.Name + "="))
{
output.Add(prop.Name + "=" + prop.Value);
}
else
{
output.Add(line);
}
}
sr.Close();
}
}
if (!output.Contains(prop.Name + "=" + prop.Value))
{
output.Add(prop.Name + "=" + prop.Value);
}
StreamWriter sw = new StreamWriter(FileName, false, Encoding.Default);
foreach (String s in output)
{
sw.WriteLine(s);
}
sw.Close();
sw.Dispose();
GC.SuppressFinalize(sw);
sw = null;
output.Clear();
output = null;
}
public void Save()
{
foreach (ConfigProperty cp in CFCollection)
{
SaveConfigProperty(cp);
}
}
public void UpdateValue(String propertyName, String propertyValue)
{
try
{
IEnumerable<ConfigProperty> myProps = CFCollection.Where(cp => cp.Name.Equals(propertyName));
if (myProps.Count() == 1)
{
myProps.ElementAt(0).Value = propertyValue;
}
else if (myProps.Count() == 0)
{
CFCollection.Add(new ConfigProperty(propertyName, propertyValue));
}
else
{
throw new Exception("Can't find/set value for: " + propertyName);
}
}
catch (Exception ex)
{
throw ex;
}
}
public String ToString(String propertyName)
{
try
{
return CFCollection.Where(cp => cp.Name.Equals(propertyName)).First().Value;
}
catch (Exception ex)
{
throw new Exception("Can't find/read value for: " +
propertyName, ex);
}
}
}
}
答案 4 :(得分:1)
您可以使用简单的普通文件。
将List<int> list
保存到file.txt
:
System.IO.File.WriteAllLines("file.txt", list.Select(v => v.ToString()).ToArray());
装载:
List<int> loaded = System.IO.File.ReadAllLines("file.txt").Select(l => int.Parse(l)).ToList();
使用扩展方法设计更好的语法和正确的错误处理
UPD :我可以提出的通用扩展方法(无异常处理):
public static class MyExtensions
{
public static void SaveToFile<T>(this List<T> list, string filename)
{
System.IO.File.WriteAllLines(filename, list.Select(v => v.ToString()).ToArray());
}
public static void FillFromFile<T>(this List<T> list, string filename, Func<string, T> parser)
{
foreach (var line in System.IO.File.ReadAllLines(filename))
{
T item = parser(line);
list.Add(item);
}
}
}
使用它:
List<int> list = new List<int>() { 0, 1, 2 };
list.SaveToFile("numbers.txt");
List<int> loaded = new List<int>();
loaded.FillFromFile("numbers.txt", (l) => int.Parse(l));
答案 5 :(得分:1)
我想建议JSON格式
格式化文件看起来像
{ “DevCommentVisibility”:27, “CommentVisibility”:1, “IssueStatusAfterCheckin”:4, “日志”:{ “调试”:假, “信息”:真, “警告”:真, “文件名”:” d:\ TEMP \ 2.登录 “},” 语言 “:” EN“}
public static string Serialize(T pSettings)
{
return (new JavaScriptSerializer()).Serialize(pSettings);
}
public static T Load(string fileName)
{
T t = new T();
if (File.Exists(fileName))
try
{
t = (new JavaScriptSerializer()).Deserialize<T>(File.ReadAllText(fileName));
var s = t as SettingsFoo;
if (s != null)
s.FileName = fileName;
}
catch (Exception ex)
{
Trace.WriteLine(string.Format("failed to parse settings file {0}", fileName));
Trace.WriteLine(ex.Message);
}
else
{
Trace.WriteLine(string.Format("failed load settings '{0}' absolute '{1}'", fileName, Path.GetFullPath(fileName)));
Save(t);
}
return t;
}