-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJsonManager.cs
172 lines (157 loc) · 5.75 KB
/
JsonManager.cs
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
164
165
166
167
168
169
170
171
172
// ============================================================================
//
// JSON 形式で設定の保存と読み込みを管理
// Copyright (C) 2023-2024 by SHINTA
//
// ============================================================================
// ----------------------------------------------------------------------------
// 保存場所は MSIX かどうかによって変わる
// 同じオプションの場合は JsonSerializerOptions を使い回す必要がある
// https://learn.microsoft.com/ja-jp/dotnet/standard/serialization/system-text-json/configure-options?pivots=dotnet-7-0#reuse-jsonserializeroptions-instances
// ----------------------------------------------------------------------------
// ============================================================================
// Ver. | 更新日 | 更新内容
// ----------------------------------------------------------------------------
// 1.00 | 2023/08/19 (Sat) | ファーストバージョン。
// (1.01) | 2023/09/17 (Sun) | Load() のオーバーロードを作成。
// (1.04) | 2024/04/08 (Mon) | MSIX ではない馬合の保存先を変更。
// (1.05) | 2024/05/20 (Mon) | Load() のパスを改善。
// ============================================================================
using System.IO.Compression;
using System.Text;
using System.Text.Json;
namespace Shinta;
internal class JsonManager
{
// ====================================================================
// public 関数
// ====================================================================
#pragma warning disable CA1822
/// <summary>
/// 設定を読み込み
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path">相対パスの場合はデフォルトのフォルダー配下から読み込み</param>
/// <param name="decompress"></param>
/// <param name="options">同じオプションの場合は同じインスタンスを渡すこと</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public T Load<T>(String path, Boolean decompress, JsonSerializerOptions? options)
{
String json = LoadJsonString(path, decompress);
return JsonSerializer.Deserialize<T>(json, options) ?? throw new Exception("設定を復元できませんでした:" + path);
}
/// <summary>
/// 設定を読み込み
/// </summary>
/// <param name="type"></param>
/// <param name="path"></param>
/// <param name="decompress"></param>
/// <param name="options"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public Object Load(Type type, String path, Boolean decompress, JsonSerializerOptions? options)
{
String json = LoadJsonString(path, decompress);
return JsonSerializer.Deserialize(json, type, options) ?? throw new Exception("設定を復元できませんでした:" + path);
}
/// <summary>
/// 設定を保存
/// </summary>
/// <param name="settings"></param>
/// <param name="path">相対パスの場合はデフォルトのフォルダー配下に保存</param>
/// <param name="compress"></param>
/// <param name="options">同じオプションの場合は同じインスタンスを渡すこと</param>
/// <exception cref="Exception"></exception>
public void Save(Object settings, String path, Boolean compress, JsonSerializerOptions? options = default)
{
String json = JsonSerializer.Serialize(settings, options);
path = AdjustPath(path);
Directory.CreateDirectory(Path.GetDirectoryName(path) ?? throw new Exception("設定保存先が不正です:" + path));
if (compress)
{
Compress(json, path);
}
else
{
File.WriteAllText(path, json, Encoding.UTF8);
}
}
#pragma warning restore CA1822
// ====================================================================
// private 定数
// ====================================================================
/// <summary>
/// zip ファイル中のエントリ名(特に意味があるわけではない名前なので短くて良い)
/// </summary>
private const String FILE_NAME_COMPRESS = "0";
// ====================================================================
// private 関数
// ====================================================================
/// <summary>
/// 保存先を調整
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private static String AdjustPath(String path)
{
if (Path.IsPathRooted(path))
{
// 絶対パスの場合はそのパスを使用
return path;
}
else
{
// 相対パスの場合は設定フォルダー配下
return CommonWindows.SettingsFolder() + path;
}
}
/// <summary>
/// json を圧縮して保存
/// </summary>
/// <param name="json"></param>
/// <param name="path"></param>
private static void Compress(String json, String path)
{
String folder = Common.TempPath();
Directory.CreateDirectory(folder);
File.WriteAllText(folder + "\\" + FILE_NAME_COMPRESS, json, Encoding.UTF8);
try
{
File.Delete(path);
}
catch (Exception)
{
}
ZipFile.CreateFromDirectory(folder, path, CompressionLevel.SmallestSize, false);
}
/// <summary>
/// zip から json を展開
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private static String Decompress(String path)
{
String folder = Common.TempPath();
ZipFile.ExtractToDirectory(path, folder);
return File.ReadAllText(folder + "\\" + FILE_NAME_COMPRESS, Encoding.UTF8);
}
/// <summary>
/// JSON 文字列の読み込み
/// </summary>
/// <param name="path"></param>
/// <param name="decompress"></param>
/// <returns></returns>
private static String LoadJsonString(String path, Boolean decompress)
{
path = AdjustPath(path);
if (decompress)
{
return Decompress(path);
}
else
{
return File.ReadAllText(path, Encoding.UTF8);
}
}
}