FilePackageTool.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. //************************************************************************
  2. // https://github.com/yuzhengyang
  3. // author: yuzhengyang
  4. // date: 2017.6.10 - 2017.6.12
  5. // desc: 文件打包工具
  6. // Copyright (c) yuzhengyang. All rights reserved.
  7. //************************************************************************
  8. using System;
  9. using System.Collections;
  10. using System.Collections.Generic;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Resources;
  14. using System.Runtime.Serialization.Formatters.Binary;
  15. using System.Text;
  16. using Y.Utils.DataUtils.Collections;
  17. namespace Y.Utils.IOUtils.FileUtils
  18. {
  19. /// <summary>
  20. /// 文件打包工具
  21. /// </summary>
  22. public class FilePackageTool
  23. {
  24. private static string FileTypeDesc = "FilePackage [文件打包]";
  25. private static int FileBuffer = 1024 * 1024;
  26. #region 类型单一,文件处理复杂,加载占用超大内存(这都是辣鸡)
  27. /// <summary>
  28. /// 批量打包任意对象到资源文件
  29. /// </summary>
  30. /// <param name="objCollection">被打包对象的列表。键值对中键为其在资源文件中的唯一标示名。</param>
  31. /// <param name="targetFilePath">目标资源文件。默认参数为当前目录下的"MyRes.pck"文件。</param>
  32. /// <param name="overwrite">是否覆盖已存在的目标文件。默认=True</param>
  33. public static void ResourcePackage(IDictionary<string, object> objCollection, string targetFilePath, bool overwrite = true)
  34. {
  35. if (overwrite) File.Delete(targetFilePath);
  36. using (ResourceWriter rw = new ResourceWriter(targetFilePath))
  37. {
  38. foreach (KeyValuePair<string, object> pair in objCollection)
  39. //为了防传进来的资源名有数字开头,资源名都加了前缀_
  40. rw.AddResource("_" + pair.Key, pair.Value);
  41. rw.Generate();
  42. rw.Close();
  43. }
  44. }
  45. /// <summary>
  46. /// 解包资源文件,返回所有资源及其资源名
  47. /// </summary>
  48. /// <param name="targetFilePath">要解包的资源文件。默认为当前目录下的"MyRes.pck"</param>
  49. /// <returns>资源字典,键值为资源唯一标示名。若无资源返回空集合。</returns>
  50. public static Dictionary<string, object> ResourceUnpack(string targetFilePath)
  51. {
  52. Dictionary<string, object> rtn = new Dictionary<string, object>();
  53. using (ResourceReader rr = new ResourceReader(targetFilePath))
  54. {
  55. foreach (DictionaryEntry entry in rr)
  56. rtn.Add(((string)entry.Key).Substring(1), entry.Value);
  57. }
  58. return rtn;
  59. }
  60. /// <summary>
  61. /// 根据资源名在指定的资源文件中检索资源
  62. /// </summary>
  63. /// <param name="resName">资源名</param>
  64. /// <param name="targetFilePath">要在其中检索的资源文件名,默认为"MyRes.pck"</param>
  65. /// <returns>资源名对应的资源</returns>
  66. public static object ResourceSearch(string resName, string targetFilePath)
  67. {
  68. object rtn = null;
  69. using (ResourceReader rr = new ResourceReader(targetFilePath))
  70. {
  71. foreach (DictionaryEntry entry in rr)
  72. if ((string)entry.Key == '_' + resName)
  73. {
  74. rtn = entry.Value;
  75. break;
  76. }
  77. }
  78. return rtn;
  79. }
  80. /// <summary>
  81. /// 将对象序列化
  82. /// </summary>
  83. /// <param name="FilePath">文件(支持绝大多数数据类型)</param>
  84. /// <param name="obj">要序列化的对象(如哈希表,数组等等)</param>
  85. public static void FileSerialize(string FilePath, object obj)
  86. {
  87. if (File.Exists(FilePath))
  88. {
  89. try
  90. {
  91. FileStream fs = new FileStream(FilePath, FileMode.Create);
  92. BinaryFormatter sl = new BinaryFormatter();
  93. sl.Serialize(fs, obj);
  94. fs.Close();
  95. }
  96. catch
  97. {
  98. //序列化存储失败!
  99. }
  100. }
  101. else
  102. {
  103. //您读取的文件对象不存在
  104. }
  105. }
  106. /// <summary>
  107. /// 将文件反序列化
  108. /// </summary>
  109. /// <param name="FilePath">文件路径(必须是经过当前序列化后的文件)</param>
  110. /// <returns>返回 null 表示序列反解失败或者目标文件不存在</returns>
  111. public static object FileDeSerialize(string FilePath)
  112. {
  113. if (System.IO.File.Exists(FilePath))
  114. {
  115. try
  116. {
  117. FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
  118. BinaryFormatter sl = new BinaryFormatter();
  119. object obg = sl.Deserialize(fs);
  120. fs.Close();
  121. return obg;
  122. }
  123. catch
  124. {
  125. return null;
  126. }
  127. }
  128. else
  129. {
  130. return null;
  131. }
  132. }
  133. #endregion
  134. /// <summary>
  135. /// 打包
  136. /// </summary>
  137. /// <returns></returns>
  138. public static int Pack(string srcPath, string dstFile, bool overwrite = true)
  139. {
  140. DateTime beginTime = DateTime.Now;
  141. if (!Directory.Exists(srcPath)) return -11; //要打包的路径不存在
  142. if (File.Exists(dstFile) && !overwrite) return -12;//打包后的目标文件已存在
  143. List<string> allfile = FileTool.GetAllFile(srcPath);
  144. if (ListTool.HasElements(allfile))
  145. {
  146. using (FileStream fsWrite = new FileStream(dstFile, FileMode.Create))
  147. {
  148. allfile.ForEach(x =>
  149. {
  150. using (FileStream fsRead = new FileStream(x, FileMode.Open))
  151. {
  152. fsRead.Close();
  153. }
  154. });
  155. fsWrite.Close();
  156. }
  157. }
  158. else
  159. {
  160. return -13;//要打包的路径中没有文件
  161. }
  162. return (int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds);//操作成功
  163. }
  164. /// <summary>
  165. /// 解包
  166. /// </summary>
  167. /// <returns></returns>
  168. public static int Unpack(string srcFile, string dstPath, bool overwrite = true)
  169. {
  170. DateTime beginTime = DateTime.Now;
  171. if (!File.Exists(srcFile)) return -11; //要解包的文件不存在
  172. if (Directory.Exists(dstPath) && !overwrite) return -12;//要解包的目标文件夹已存在
  173. return (int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds);//操作成功
  174. }
  175. }
  176. }