246 lines
8.6 KiB
C#
246 lines
8.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
namespace AibisDream.Utility
|
|
{
|
|
public static class JsonUtil
|
|
{
|
|
public const string JsonSuffix = ".json";
|
|
|
|
// 缓存的 JsonSerializerSettings,优化性能
|
|
private static readonly JsonSerializerSettings _defaultSettings = new JsonSerializerSettings
|
|
{
|
|
// 禁用类型名称处理,提升性能
|
|
TypeNameHandling = TypeNameHandling.None,
|
|
// 使用默认的日期格式处理
|
|
DateFormatHandling = DateFormatHandling.IsoDateFormat,
|
|
// 忽略循环引用
|
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
|
|
// 注意:不设置 NullValueHandling,保持默认行为(Include),避免改变现有功能
|
|
};
|
|
|
|
// 缓存的 JsonSerializer 实例,用于字典反序列化优化
|
|
private static readonly JsonSerializer _cachedSerializer = JsonSerializer.Create(_defaultSettings);
|
|
|
|
/// <summary>
|
|
/// 根据平台读取文件内容
|
|
/// </summary>
|
|
private static string ReadFileText(string filePath)
|
|
{
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
// Android 平台需要使用 UnityWebRequest 读取 StreamingAssets
|
|
if (filePath.Contains(Application.streamingAssetsPath))
|
|
{
|
|
// Android 上 StreamingAssets 在 APK 中,需要构建正确的 URL
|
|
string url = filePath;
|
|
// 确保使用正确的路径分隔符
|
|
url = url.Replace("\\", "/");
|
|
// 如果路径不包含协议前缀,添加 file://
|
|
if (!url.StartsWith("file://") && !url.StartsWith("jar:file://"))
|
|
{
|
|
// 对于 Android APK 中的文件,使用 jar:file:// 协议
|
|
string relativePath = url.Replace(Application.streamingAssetsPath, "").TrimStart('/');
|
|
url = "jar:file://" + Application.dataPath + "!/assets/" + relativePath;
|
|
}
|
|
|
|
using (UnityWebRequest www = UnityWebRequest.Get(url))
|
|
{
|
|
www.SendWebRequest();
|
|
|
|
// 等待请求完成(同步等待)
|
|
while (!www.isDone)
|
|
{
|
|
// 在主线程中等待
|
|
}
|
|
|
|
if (www.result == UnityWebRequest.Result.Success)
|
|
{
|
|
return www.downloadHandler.text;
|
|
}
|
|
else
|
|
{
|
|
throw new IOException($"无法读取文件: {filePath}, URL: {url}, 错误: {www.error}");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 非 StreamingAssets 路径,使用普通文件读取
|
|
return File.ReadAllText(filePath);
|
|
}
|
|
#else
|
|
// 其他平台直接使用 File 类
|
|
return File.ReadAllText(filePath);
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// 按路径和Key加载
|
|
/// </summary>
|
|
/// <param name="path">路径</param>
|
|
/// <param name="key">key</param>
|
|
/// <typeparam name="T">类型</typeparam>
|
|
/// <returns>Bean</returns>
|
|
/// <exception cref="Exception">错误</exception>
|
|
public static T ReadBean<T>(string path, string key)
|
|
{
|
|
string json = ReadFileText(path);
|
|
JObject jObject = JObject.Parse(json);
|
|
|
|
if (jObject.ContainsKey(key))
|
|
{
|
|
return jObject.ToObject<T>();
|
|
}
|
|
|
|
throw new Exception("没有找到对应的Key");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 按路径加载Json
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static T ReadBean<T>(string path)
|
|
{
|
|
string json = ReadFileText(path);
|
|
return JsonConvert.DeserializeObject<T>(json, _defaultSettings);
|
|
}
|
|
|
|
public static T ReadBeanByText<T>(string text)
|
|
{
|
|
if (!text.StartsWith("{"))
|
|
{
|
|
text = "{" + text + "}";
|
|
}
|
|
return JsonConvert.DeserializeObject<T>(text, _defaultSettings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 按路径加载Json
|
|
/// </summary>
|
|
/// <param name="path">路径</param>
|
|
/// <typeparam name="T">Bean</typeparam>
|
|
/// <returns>目标Bean</returns>
|
|
public static T[] ReadBeanArray<T>(string path)
|
|
{
|
|
string json = ReadFileText(path);
|
|
return JsonConvert.DeserializeObject<T[]>(json, _defaultSettings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 按路径加载Json
|
|
/// </summary>
|
|
/// <param name="path">路径</param>
|
|
/// <typeparam name="T">Bean</typeparam>
|
|
/// <returns>目标Bean</returns>
|
|
public static Dictionary<string, T> ReadBeanDict<T>(string path)
|
|
{
|
|
string json = ReadFileText(path);
|
|
|
|
// 使用缓存的 JsonSerializerSettings 和 StringReader 优化性能
|
|
using (var reader = new StringReader(json))
|
|
using (var jsonReader = new JsonTextReader(reader))
|
|
{
|
|
var result = _cachedSerializer.Deserialize<Dictionary<string, T>>(jsonReader);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取Json中的Key列表
|
|
/// </summary>
|
|
/// <param name="path">路径</param>
|
|
/// <returns>key列表</returns>
|
|
public static string[] ReadKeys(string path)
|
|
{
|
|
string json = ReadFileText(path);
|
|
JObject jObject = JObject.Parse(json);
|
|
|
|
return jObject.Properties().Select(jProp => jProp.Name).ToArray();
|
|
}
|
|
|
|
public static JObject ReadJObject(string path)
|
|
{
|
|
string json = ReadFileText(FormatAsJsonPath(path));
|
|
return JObject.Parse(json);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存Bean
|
|
/// </summary>
|
|
/// <param name="bean">bean</param>
|
|
/// <param name="path">路径</param>
|
|
/// <typeparam name="T">类型</typeparam>
|
|
public static void SaveBean<T>(T bean, string path)
|
|
{
|
|
string json = JsonConvert.SerializeObject(bean);
|
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
|
File.WriteAllText(path, json);
|
|
}
|
|
|
|
public static void SaveJObject(JObject jObject, string path)
|
|
{
|
|
string json = jObject.ToString();
|
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
|
File.WriteAllText(FormatAsJsonPath(path), json);
|
|
}
|
|
|
|
public static void SaveArray<T>(T[] array, string path)
|
|
{
|
|
string json = JsonConvert.SerializeObject(array);
|
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
|
File.WriteAllText(FormatAsJsonPath(path), json);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存类
|
|
/// </summary>
|
|
/// <param name="bean">对象</param>
|
|
/// <param name="key">key</param>
|
|
/// <param name="path">保存配置</param>
|
|
/// <param name="saveMode">添加还是覆盖</param>
|
|
/// <typeparam name="T">类型</typeparam>
|
|
public static void SaveBean<T>(T bean, string key, string path, SaveMode saveMode = SaveMode.Add)
|
|
{
|
|
if (saveMode == SaveMode.Add && File.Exists(path))
|
|
{
|
|
Dictionary<string, T> originDic = JsonConvert.DeserializeObject<Dictionary<string, T>>(path);
|
|
originDic.Add(key, bean);
|
|
string tempJson = JsonConvert.SerializeObject(originDic);
|
|
File.WriteAllText(path, tempJson);
|
|
}
|
|
else
|
|
{
|
|
Dictionary<string, T> tempDic = new Dictionary<string, T> { { key, bean } };
|
|
string tempJson = JsonConvert.SerializeObject(tempDic);
|
|
File.WriteAllText(path, tempJson);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 自动把文件名转为Json
|
|
/// </summary>
|
|
/// <param name="fileName">文件名</param>
|
|
/// <returns>已改为json的文件名</returns>
|
|
public static string FormatAsJsonPath(string fileName)
|
|
{
|
|
if (!fileName.EndsWith(JsonSuffix))
|
|
{
|
|
return fileName + JsonSuffix;
|
|
}
|
|
|
|
return fileName;
|
|
}
|
|
}
|
|
|
|
public enum SaveMode
|
|
{
|
|
Replace,
|
|
Add
|
|
}
|
|
} |