Unity 框架

FileOperations.cs 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. using Cysharp.Threading.Tasks;
  2. using Newtonsoft.Json;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Runtime.Serialization.Formatters.Binary;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using UnityEngine;
  12. namespace TFramework
  13. {
  14. /// <summary>
  15. /// 文件操作
  16. /// </summary>
  17. public static class FileOperations
  18. {
  19. /// <summary>
  20. /// 路径暂存列表
  21. /// </summary>
  22. static List<string> paths = new List<string>();
  23. #region Json
  24. static JsonSerializerSettings settings = new JsonSerializerSettings
  25. {
  26. TypeNameHandling = TypeNameHandling.Auto, // 或 TypeNameHandling.All
  27. Formatting = Formatting.Indented,
  28. ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
  29. };
  30. /// <summary>
  31. /// 写入Json数据
  32. /// </summary>
  33. /// <param name="data">数据</param>
  34. /// <param name="path">文件完整路径</param>
  35. public static void WriteJsonData(object data, string path)
  36. {
  37. string json = JsonConvert.SerializeObject(data, settings);
  38. WriteData(json, path);
  39. }
  40. /// <summary>
  41. /// 异步写入Json数据
  42. /// </summary>
  43. /// <param name="data">数据</param>
  44. /// <param name="path">文件完整路径</param>
  45. public async static UniTask WriteJsonDataAsync(object data, string path)
  46. {
  47. string json = JsonConvert.SerializeObject(data, settings);
  48. await WriteDataAsync(json, path);
  49. }
  50. /// <summary>
  51. /// 读取Json数据
  52. /// </summary>
  53. /// <typeparam name="T">数据类型</typeparam>
  54. /// <param name="path">数据完整路径</param>
  55. /// <returns></returns>
  56. public static T ReadJsonData<T>(string path)
  57. {
  58. if (FileExists(path))
  59. return JsonConvert.DeserializeObject<T>(ReadText(path), settings);
  60. else
  61. return default(T);
  62. }
  63. /// <summary>
  64. /// 异步读取Json数据
  65. /// </summary>
  66. /// <typeparam name="T">数据类型</typeparam>
  67. /// <param name="path">数据完整路径</param>
  68. /// <returns></returns>
  69. public static async UniTask<T> ReadJsonDataAsync<T>(string path)
  70. {
  71. if (FileExists(path))
  72. return JsonConvert.DeserializeObject<T>(await ReadTextAsync(path), settings);
  73. else
  74. return default(T);
  75. }
  76. #endregion
  77. /// <summary>
  78. /// 写入数据
  79. /// </summary>
  80. /// <param name="value">要写入的数据</param>
  81. /// <param name="path">数据完整路径</param>
  82. public static void WriteData(string value, string path)
  83. {
  84. //打开或者新建文档
  85. using (StreamWriter sw = new StreamWriter(path))
  86. {
  87. //保存数据
  88. sw.WriteLine(value);
  89. //关闭文档
  90. sw.Close();
  91. sw.Dispose();
  92. }
  93. }
  94. /// <summary>
  95. /// 异步写入数据
  96. /// </summary>
  97. /// <param name="value">要写入的数据</param>
  98. /// <param name="path">数据完整路径</param>
  99. public static async UniTask WriteDataAsync(string value, string path)
  100. {
  101. //打开或者新建文档
  102. using (StreamWriter sw = new StreamWriter(path))
  103. {
  104. //保存数据
  105. await sw.WriteAsync(value);
  106. //关闭文档
  107. sw.Close();
  108. sw.Dispose();
  109. }
  110. }
  111. /// <summary>
  112. /// 以二进制形式写入数据
  113. /// </summary>
  114. /// <param name="obj">数据</param>
  115. /// <param name="path">数据完整路径</param>
  116. public static void WriteBinaryData(System.Object obj, string path)
  117. {
  118. try
  119. {
  120. string folderPath = path.Remove(path.LastIndexOf('/'));
  121. if (!Directory.Exists(folderPath))
  122. Directory.CreateDirectory(folderPath);
  123. BinaryFormatter binary = new BinaryFormatter();
  124. using (FileStream fs = File.Create(path))
  125. {
  126. binary.Serialize(fs, obj);
  127. }
  128. }
  129. catch (Exception e)
  130. {
  131. Log.Error(e.Message);
  132. }
  133. }
  134. /// <summary>
  135. /// 读取二进制文件
  136. /// </summary>
  137. /// <typeparam name="T">文件类型</typeparam>
  138. /// <param name="path">文件路径</param>
  139. /// <returns></returns>
  140. public static T ReadBinaryData<T>(string path)
  141. {
  142. try
  143. {
  144. BinaryFormatter binary = new BinaryFormatter();
  145. using (FileStream fs = File.Open(path, FileMode.Open))
  146. {
  147. return (T)binary.Deserialize(fs);
  148. }
  149. }
  150. catch (Exception e)
  151. {
  152. Log.Info(e.Message);
  153. return default(T);
  154. }
  155. }
  156. public static byte[] SafeReadAllBytes(string inFile)
  157. {
  158. try
  159. {
  160. if (string.IsNullOrEmpty(inFile) || !File.Exists(inFile))
  161. return null;
  162. File.SetAttributes(inFile, FileAttributes.Normal);
  163. return File.ReadAllBytes(inFile);
  164. }
  165. catch (System.Exception ex)
  166. {
  167. Log.Error(string.Format("SafeReadAllBytes failed! path = {0} with err = {1}", inFile, ex.Message));
  168. return null;
  169. }
  170. }
  171. /// <summary>
  172. /// 读取文本数据
  173. /// </summary>
  174. /// <param name="path">数据完整路径</param>
  175. /// <returns></returns>
  176. public static string ReadText(string path)
  177. {
  178. if (!File.Exists(path)) return null;
  179. using (StreamReader str = new StreamReader(path, Encoding.UTF8))
  180. {
  181. if (str == null) return null;
  182. return str.ReadToEnd();
  183. }
  184. }
  185. /// <summary>
  186. /// 异步读取文本数据
  187. /// </summary>
  188. /// <param name="path">数据完整路径</param>
  189. /// <returns></returns>
  190. public async static UniTask<string> ReadTextAsync(string path)
  191. {
  192. if (!File.Exists(path)) return null;
  193. using (StreamReader str = new StreamReader(path, Encoding.UTF8))
  194. {
  195. if (str == null) return null;
  196. return await str.ReadToEndAsync();
  197. }
  198. }
  199. /// <summary>
  200. /// 读取Texture2D文件
  201. /// </summary>
  202. /// <param name="path"></param>
  203. /// <returns></returns>
  204. public static Texture2D ReadTexture2D(string path)
  205. {
  206. if (!File.Exists(path))
  207. return null;
  208. FileStream fs = new FileStream(path, FileMode.Open);
  209. byte[] buffer = new byte[fs.Length];
  210. fs.Read(buffer, 0, buffer.Length);
  211. fs.Close();
  212. Texture2D originalTex = new Texture2D(2, 2);
  213. var iSLoad = originalTex.LoadImage(buffer);
  214. originalTex.Apply();
  215. if (iSLoad)
  216. return originalTex;
  217. else
  218. return null;
  219. }
  220. /// <summary>
  221. /// 获取文件夹下所有文件路径
  222. /// </summary>
  223. /// <param name="dir">文件夹路径</param>
  224. /// <param name="excludeFile">要排除的文件的后缀</param>
  225. /// <returns></returns>
  226. public static string[] GetFolderAllFilePath(string dir, params string[] excludeFile)
  227. {
  228. paths.Clear();
  229. FindFile(dir, excludeFile);
  230. return paths.ToArray();
  231. }
  232. static void FindFile(string dir, params string[] excludeFile)
  233. {
  234. DirectoryInfo info = new DirectoryInfo(dir);
  235. FileSystemInfo[] file = info.GetFileSystemInfos();
  236. foreach (var item in file)
  237. {
  238. if (item is DirectoryInfo)
  239. FindFile(item.FullName, excludeFile);
  240. else
  241. {
  242. if (excludeFile != null)
  243. {
  244. string suffix = item.Extension;
  245. bool isAdd = true;
  246. foreach (var su in excludeFile)
  247. {
  248. if (suffix == su)
  249. isAdd = false;
  250. }
  251. if (isAdd)
  252. paths.Add(item.FullName);
  253. }
  254. else
  255. paths.Add(item.FullName);
  256. }
  257. }
  258. }
  259. /// <summary>
  260. /// 获取路径下所有文件夹路径
  261. /// </summary>
  262. /// <param name="path">路径</param>
  263. /// <returns></returns>
  264. public static string[] GetPathAllFolders(string path)
  265. {
  266. paths.Clear();
  267. FindFolders(path);
  268. return paths.ToArray();
  269. }
  270. static void FindFolders(string path)
  271. {
  272. DirectoryInfo info = new DirectoryInfo(path);
  273. FileSystemInfo[] file = info.GetFileSystemInfos();
  274. foreach (var item in file)
  275. {
  276. if (item is DirectoryInfo)
  277. {
  278. FindFolders(item.FullName);
  279. paths.Add(item.FullName);
  280. }
  281. }
  282. }
  283. /// <summary>
  284. /// 拷贝文件夹
  285. /// </summary>
  286. /// <param name="sourceDirName"></param>
  287. /// <param name="destDirName"></param>
  288. /// <param name="isOverlay">是否覆盖已有同名文件</param>
  289. public static void CopyDirectory(string sourceDirName, string destDirName,bool isOverlay=false)
  290. {
  291. try
  292. {
  293. if (!Directory.Exists(destDirName))
  294. {
  295. Directory.CreateDirectory(destDirName);
  296. File.SetAttributes(destDirName, File.GetAttributes(sourceDirName));
  297. }
  298. if (destDirName[destDirName.Length - 1] != Path.DirectorySeparatorChar)
  299. destDirName = destDirName + Path.DirectorySeparatorChar;
  300. string[] files = Directory.GetFiles(sourceDirName);
  301. foreach (string file in files)
  302. {
  303. if (File.Exists(destDirName + Path.GetFileName(file))&&!isOverlay)
  304. continue;
  305. FileInfo fileInfo = new FileInfo(file);
  306. if (fileInfo.Extension.Equals(".meta", StringComparison.CurrentCultureIgnoreCase))
  307. continue;
  308. File.Copy(file, destDirName + Path.GetFileName(file), true);
  309. File.SetAttributes(destDirName + Path.GetFileName(file), FileAttributes.Normal);
  310. }
  311. string[] dirs = Directory.GetDirectories(sourceDirName);
  312. foreach (string dir in dirs)
  313. {
  314. CopyDirectory(dir, destDirName + Path.GetFileName(dir),isOverlay);
  315. }
  316. }
  317. catch (Exception ex)
  318. {
  319. throw ex;
  320. }
  321. }
  322. /// <summary>
  323. /// 拷贝文件
  324. /// </summary>
  325. /// <param name="sourceFileNmae"></param>
  326. /// <param name="destFlieName"></param>
  327. public static void CopyFile(string sourceFileNmae,string destFlieName)
  328. {
  329. FileInfo file = new FileInfo(sourceFileNmae);
  330. if (file.Exists)
  331. file.CopyTo(destFlieName, true);
  332. else
  333. Log.Error($"目标文件【{sourceFileNmae}】不存在!");
  334. }
  335. /// <summary>
  336. /// 检查文件路径是否存在
  337. /// </summary>
  338. /// <param name="path"></param>
  339. /// <returns></returns>
  340. public static bool FileExists(string path) => File.Exists(path);
  341. /// <summary>
  342. /// 检查文件夹是否存在
  343. /// </summary>
  344. /// <param name="path"></param>
  345. /// <returns></returns>
  346. public static bool FolderExists(string path) => Directory.Exists(path);
  347. /// <summary>
  348. /// 获取文件夹下指定类型文件信息
  349. /// </summary>
  350. /// <param name="folder">文件夹</param>
  351. /// <param name="suffix">后缀</param>
  352. /// <returns></returns>
  353. public static FileInfo[] GetFiles(string folder, string suffix)
  354. {
  355. if (!Directory.Exists(folder)) return null;
  356. DirectoryInfo di = new DirectoryInfo(folder);
  357. return di.GetFiles().ToList().Where(p => p.Extension == suffix).Select(p => p).ToArray();
  358. }
  359. /// <summary>
  360. /// 获取文件夹下指定类型文件信息
  361. /// </summary>
  362. /// <param name="folder">文件夹</param>
  363. /// <param name="suffix">后缀</param>
  364. /// <returns></returns>
  365. public static FileInfo[] GetFiles(string folder, string suffix, IComparer comparer)
  366. {
  367. if (!Directory.Exists(folder)) return null;
  368. DirectoryInfo di = new DirectoryInfo(folder);
  369. FileInfo[] fileInfo = di.GetFiles().ToList().Where(p => p.Extension == suffix).Select(p => p).ToArray();
  370. Array.Sort(fileInfo, comparer);
  371. return fileInfo;
  372. }
  373. /// <summary>
  374. /// 按时间排序
  375. /// </summary>
  376. /// <returns></returns>
  377. public static IComparer SortToTime => new FileTimeComparer();
  378. public class FileTimeComparer : IComparer
  379. {
  380. public int Compare(object x, object y)
  381. {
  382. FileInfo file1 = x as FileInfo;
  383. FileInfo file2 = y as FileInfo;
  384. return file1.LastWriteTime.CompareTo(file2.LastWriteTime);
  385. }
  386. }
  387. public static void CreateFloder(string path) => Directory.CreateDirectory(path);
  388. /// <summary>
  389. /// 创建项目绝对路径文件夹
  390. /// </summary>
  391. /// <param name="path"></param>
  392. public static void CreateAbsoluteFloder(string path)
  393. {
  394. CreateFloder(GetAbsolutePath(path));
  395. }
  396. /// <summary>
  397. /// 获取相对项目路径的绝对路径
  398. /// </summary>
  399. /// <param name="path"></param>
  400. /// <returns></returns>
  401. public static string GetAbsolutePath(string path)
  402. {
  403. string _path = Application.dataPath.Remove(Application.dataPath.LastIndexOf('/') + 1);
  404. return _path + path;
  405. }
  406. }
  407. }