WPF配置文件读写的几种方式(本地存储)

项目配置文件

直接读写项目本身的配置文件

项目本身的配置文件是支持读写的,但是这里不建议写,只建议读。

原因如下:

  • 开发过程中每次重启都会覆盖。
  • Net Core的配置不支持写入,所有代码切换框架不方便。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/// <summary>
/// 读取设置
/// </summary>
/// <param name="settingName"></param>
/// <returns></returns>
public static string GetSettingString(string settingName)
{
try
{
string settingString = ConfigurationManager.AppSettings[settingName].ToString();
return settingString;
}
catch (Exception)
{
return null;
}
}

/// <summary>
/// 更新设置
/// </summary>
/// <param name="settingName"></param>
/// <param name="valueName"></param>
public static void UpdateSettingString(string settingName, string valueName)
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

if (ConfigurationManager.AppSettings[settingName] != null)
{
config.AppSettings.Settings.Remove(settingName);
}
config.AppSettings.Settings.Add(settingName, valueName);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}

自定义XML配置(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using System;
using System.Configuration;

namespace Z.Utils.Common
{
public static class ZConfigAppUtil
{
///<summary>
///返回app.config文件中appSettings配置节的value项
///</summary>
///<param name="strKey"></param>
///<returns></returns>
public static string GetVaule(string strKey)
{
return GetVaule(strKey, "app.config");
}

public static string GetVaule(string strKey, string filepath)
{
ExeConfigurationFileMap file = new ExeConfigurationFileMap { ExeConfigFilename = filepath };
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(file, ConfigurationUserLevel.None);
foreach (string key in config.AppSettings.Settings.AllKeys)
{
if (key == strKey)
{
return config.AppSettings.Settings[strKey].Value;
}
}
return null;
}

///<summary>
///在app.config文件中appSettings配置节增加一对键值对
///</summary>
///<param name="newKey"></param>
///<param name="newValue"></param>
public static void SetVaule(string newKey, string newValue)
{
SetVaule(newKey, newValue, "app.config");
}

public static void SetVaule(string newKey, string newValue, string filepath)
{
ExeConfigurationFileMap file = new ExeConfigurationFileMap { ExeConfigFilename = filepath };
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(file, ConfigurationUserLevel.None);
bool exist = false;
foreach (string key in config.AppSettings.Settings.AllKeys)
{
if (key == newKey)
{
exist = true;
}
}
if (exist)
{
config.AppSettings.Settings.Remove(newKey);
}
config.AppSettings.Settings.Add(newKey, newValue);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}

public static void Test()
{
SetVaule("ServerIp", "127.0.0.1");
SetVaule("ServerPort", "10088");
Console.WriteLine("ServerIp:" + GetVaule("ServerIp"));
Console.WriteLine("ServerXXX:" + (GetVaule("ServerXXX") == null));
}
}
}

对象映射XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
using System;
using System.Data;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ZUtils
{
/// <summary>
/// 通用XML序列化和反序列化及配置保存工具类
/// </summary>
public static class ZXmlUtil
{
#region 反序列化

/// <summary>
/// 反序列化实体
/// </summary>
/// <typeparam name="T">
/// </typeparam>
/// <param name="strXML">
/// </param>
/// <returns>
/// </returns>
public static T Deserialize<T>(string strXML) where T : class
{
try
{
using (StringReader sr = new StringReader(strXML))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return serializer.Deserialize(sr) as T;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return null;
}
}

/// <summary>
/// 从文件中反序列化到实体
/// </summary>
/// <param name="objname">
/// </param>
/// <returns>
/// </returns>
public static T DeserailizeFile<T>(string savePath) where T : class
{
try
{
T obj;
if (!File.Exists(savePath))
{
throw new Exception("指定文件不存在");
}
//Xml格式反序列化
using (Stream stream = new FileStream(savePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
XmlSerializer formatter = new XmlSerializer(typeof(T));
obj = formatter.Deserialize(stream) as T;
stream.Close();
}
return obj;
}
catch (Exception)
{
return null;
}
}

/// <summary>
/// 将xml转为Datable
/// </summary>
public static DataTable Deserailize2DataTable(string xmlStr)
{
if (!string.IsNullOrEmpty(xmlStr))
{
StringReader StrStream = null;
XmlTextReader Xmlrdr = null;
try
{
DataSet ds = new DataSet();
//读取字符串中的信息
StrStream = new StringReader(xmlStr);
//获取StrStream中的数据
Xmlrdr = new XmlTextReader(StrStream);
//ds获取Xmlrdr中的数据
ds.ReadXml(Xmlrdr);
return ds.Tables[0];
}
catch (Exception)
{
return null;
}
finally
{
//释放资源
if (Xmlrdr != null)
{
Xmlrdr.Close();
StrStream.Close();
StrStream.Dispose();
}
}
}
return null;
}

#endregion 反序列化

#region 序列化

/// <summary>
/// 实体类转XML
/// </summary>
/// <typeparam name="T">
/// </typeparam>
/// <param name="obj">
/// </param>
/// <returns>
/// </returns>
public static string Serialize<T>(T obj)
{
using (StringWriter sw = new StringWriter())
{
Type t = obj.GetType();
XmlSerializer serializer = new XmlSerializer(obj.GetType());
serializer.Serialize(sw, obj);
sw.Close();
return sw.ToString();
}
}

/// <summary>
/// 实体类转XML
/// </summary>
/// <typeparam name="T">
/// </typeparam>
/// <param name="obj">
/// </param>
/// <returns>
/// </returns>
public static string Serialize<T>(T obj, string savePath)
{
using (StringWriter sw = new StringWriter())
{
Type t = obj.GetType();
XmlSerializer serializer = new XmlSerializer(obj.GetType());
serializer.Serialize(sw, obj);
sw.Close();
string xmlStr = sw.ToString();
//不用判断文件是否存在 会自动创建和覆盖
File.WriteAllText(savePath, xmlStr, Encoding.Default);
return xmlStr;
}
}

#endregion 序列化
}
}

测试

1
2
3
string path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\test.xml";
Console.WriteLine(path);
ZXmlUtil.Serialize(new AppModel(), path);

IsolatedStorageFile

这种在有隐藏配置文件需求的情况下使用。

在C#中,IsolatedStorageFile类用于访问应用程序的独立存储空间。这个类提供了一种安全的方式来存储和检索应用程序的数据,使其对应用程序的其他部分和其他应用程序是隔离的。

IsolatedStorageFile 类可以用于存储和读取用户设置、配置文件、日志文件等。它适用于那些希望在应用程序域内具有独立的存储空间的场景,例如 Windows 桌面应用程序或 Windows Phone 应用程序。

使用 IsolatedStorageFile 类的优点包括:

  1. 安全性:独立存储空间只能由授权的应用程序访问,其他应用程序无法访问或修改其中的数据。
  2. 简单易用:IsolatedStorageFile 类提供了简单的 API,使得存储和检索数据变得非常容易。

然而,随着技术的发展和新的存储选项的出现,IsolatedStorageFile 在某些方面可能已经过时。在一些情况下,可能有更好的替代方案可以满足特定需求,例如使用专用数据库引擎、云存储解决方案等。

因此,建议您根据您的具体需求和项目的要求来决定是否使用 IsolatedStorageFile。如果您的应用程序需要在应用程序域内具有独立的存储空间并需要简单的数据存储和检索功能,那么 IsolatedStorageFile 可能是一个不错的选择。但如果您需要更高级的数据存储功能或需要与其他应用程序或平台进行数据共享,那么您可能需要考虑其他存储选项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
namespace Z.Utils.Common
{
using System.IO;
using System.IO.IsolatedStorage;

public class ZAppDataHelper
{
private static readonly string DefaultName = "zapp_data.txt";

/// <summary>
/// 保存数据
/// </summary>
/// <param name="data"></param>
public static void SaveData(string data)
{
SaveData(
data,
DefaultName
);
}

public static void SaveData
(
string data,
string configName
)
{
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly())
{
using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(
configName,
FileMode.Create,
storage
))
{
using (StreamWriter writer = new StreamWriter(fileStream))
{
writer.WriteLine(data);
}
}
}
}

/// <summary>
/// 加载数据
/// </summary>
/// <returns></returns>
public static string LoadData()
{
return LoadData(DefaultName);
}

public static string LoadData(string configName)
{
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly())
{
using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(
configName,
FileMode.OpenOrCreate,
storage
))
{
using (StreamReader reader = new StreamReader(fileStream))
{
return reader.ReadLine();
}
}
}
}
}
}

存储文件位置

1
C:\Users\{用户名}\AppData\Local\IsolatedStorage

进入配置文件夹

1
cd %USERPROFILE%\AppData\Local\IsolatedStorage

打开配置文件夹

1
explorer %USERPROFILE%\AppData\Local\IsolatedStorage

实际路径

1
C:\Users\Administrator\AppData\Local\IsolatedStorage\gy1kufns.3hq\yv10plkr.z2a\Url.ve3fkgkzvqcefsybx10rmry0jjnn5gh2\AssemFiles

我们会发现它会自动生成一些加密后的路径,但是实际文件还是以文本方式存储。

文本配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
namespace env_monitor.Utils
{
using System;
using System.IO;
using System.Reflection;
using System.Text;

public class ZConfigTextUtil
{
public static string savePath;

/// <summary>
/// 配置文件是否存在 不存在则生成
/// </summary>
/// <returns></returns>
private static bool FileIsExist()
{
if (string.IsNullOrEmpty(savePath))
{
string applicationData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
savePath = Path.Combine(
applicationData,
GetApplicationName(),
"config.txt"
);
Console.WriteLine(@"savePath:" + savePath);
}
try
{
FileInfo fi = new FileInfo(savePath);
var di = fi.Directory;
if (di != null && !di.Exists)
{
di.Create();
}
return true;
}
catch (Exception)
{
return false;
}
}

/// <summary>
/// 获取应用名称
/// </summary>
/// <returns>应用名称</returns>
public static string GetApplicationName()
{
Assembly assembly = Assembly.GetEntryAssembly(); // 获取程序集信息
if (assembly != null)
{
AssemblyProductAttribute productAttribute = (AssemblyProductAttribute)Attribute.GetCustomAttribute(
assembly,
typeof(AssemblyProductAttribute)
); // 获取产品名称属性
string appName = productAttribute != null ? productAttribute.Product : "zapp";
return appName;
}
return "zapp";
}

/// <summary>
/// 读取文件
/// </summary>
/// <returns></returns>
public static string GetVaule()
{
if (FileIsExist())
{
return GetVaule(savePath);
}
return null;
}

/// <summary>
/// 写入文件
/// </summary>
/// <param name="newValue"></param>
public static void SetVaule(string newValue)
{
if (FileIsExist())
{
SetVaule(
newValue,
savePath
);
}
}

/// <summary>
/// 读取文件
/// </summary>
/// <param name="filepath"></param>
/// <returns></returns>
public static string GetVaule(string filepath)
{
if (!File.Exists(filepath)) return null;
try
{
return System.IO.File.ReadAllText(
filepath,
Encoding.Default
);
}
catch (Exception)
{
return null;
}
}

/// <summary>
/// 写入文件
/// </summary>
/// <param name="newValue"></param>
/// <param name="filepath"></param>
public static void SetVaule
(
string newValue,
string filepath
)
{
FileInfo fi = new FileInfo(filepath);
DirectoryInfo di = fi.Directory;
if (di != null && !di.Exists)
{
di.Create();
}
System.IO.File.WriteAllText(
filepath,
newValue,
Encoding.Default
);
}
}
}

JSON文本配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using Newtonsoft.Json;

using System;
using System.IO;

namespace ZUtils
{
public class ZConfigJsonUtil
{
private static string readtxt(string filepath)
{
string config_txt = "";
using (FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (StreamReader sr = new StreamReader(fs))
{
config_txt = sr.ReadToEnd();
}
}

return config_txt;
}

private static void writetxt(string filepath, string txt)
{
using (FileStream fs = new FileStream(filepath, FileMode.Truncate, FileAccess.ReadWrite))
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(txt);
}
}
}

private static string getconfigpath()
{
string docpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string configfolderpath = Path.Combine(docpath, "_XHCLASS");
if (!Directory.Exists(configfolderpath))
{
Directory.CreateDirectory(configfolderpath);
}

string configpath = Path.Combine(configfolderpath, "config.json");
return configpath;
}

/// <summary>
/// 初始化配置
/// </summary>
public static void init()
{
string configpath = getconfigpath();
string txt = readtxt(configpath);
if (string.IsNullOrEmpty(txt))
{
txt = "{}";
ConfigModel jsonobj = JsonConvert.DeserializeObject<ConfigModel>(txt);
string docpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string configfolderpath = Path.Combine(docpath, "_XHCLASS");
jsonobj.savepath = configfolderpath;
writetxt(configpath, JsonConvert.SerializeObject(jsonobj));
}
}

/// <summary>
/// 获取配置文件
/// </summary>
/// <returns></returns>
public static ConfigModel configGet()
{
string configpath = getconfigpath();
string txt = readtxt(configpath);
if (string.IsNullOrEmpty(txt))
{
txt = "{}";
}
try
{
return JsonConvert.DeserializeObject<ConfigModel>(txt); ;
}
catch (Exception)
{
return new ConfigModel();
}
}

/// <summary>
/// 保存配置文件
/// </summary>
/// <param name="config"></param>
public static void configSet(ConfigModel config)
{
string configpath = getconfigpath();
writetxt(configpath, JsonConvert.SerializeObject(config));
}

/// <summary>
/// 设置临时文件存储位置
/// </summary>
/// <param name="value"></param>
public static void setSavepath(string value)
{
ConfigModel config = configGet();
config.savepath = value;
configSet(config);
}

/// <summary>
/// 获取临时文件存储位置
/// </summary>
/// <returns></returns>
public static string getSavepath()
{
var config = configGet();
if (string.IsNullOrEmpty(config.savepath))
{
string docpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string configfolderpath = Path.Combine(docpath, "_XHCLASS");
return configfolderpath;
}
else
{
return config.savepath;
}
}
}

public class ConfigModel
{
public string savepath { get; set; }
}
}