You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

417 lines
15 KiB

  1. using Apewer;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. namespace Apewer.Internals
  6. {
  7. internal class StorageHelper
  8. {
  9. public static bool FileExists(string argPath)
  10. {
  11. if (string.IsNullOrEmpty(argPath)) return false;
  12. return System.IO.File.Exists(argPath);
  13. }
  14. public static bool DirectoryExists(string argPath)
  15. {
  16. if (string.IsNullOrEmpty(argPath)) return false;
  17. return System.IO.Directory.Exists(argPath);
  18. }
  19. public static bool PathExists(string argPath)
  20. {
  21. if (string.IsNullOrEmpty(argPath)) return false;
  22. if (System.IO.File.Exists(argPath)) return true;
  23. if (System.IO.Directory.Exists(argPath)) return true;
  24. return false;
  25. }
  26. /// <summary>获取指定目录下子文件的路径,不递归子目录。</summary>
  27. /// <param name="argDirectory">顶级目录。</param>
  28. public static List<string> GetSubFiles(string argDirectory)
  29. {
  30. return GetSubFiles(argDirectory, false, false);
  31. }
  32. /// <summary>获取指定目录下子文件的路径。</summary>
  33. /// <param name="argDirectory">顶级目录。</param>
  34. /// <param name="argRecurSub">递归子目录。</param>
  35. /// <param name="argRecurPrecedence">优先排列递归项。</param>
  36. public static List<string> GetSubFiles(string argDirectory, bool argRecurSub, bool argRecurPrecedence)
  37. {
  38. return GetSubFiles(argDirectory, argRecurSub ? -1 : 0, argRecurPrecedence);
  39. }
  40. /// <summary>获取指定目录下子文件的路径。</summary>
  41. /// <param name="argDirectory">顶级目录。</param>
  42. /// <param name="argRecurDepth">子目录递归深度。</param>
  43. /// <param name="argRecurPrecedence">优先排列递归项。</param>
  44. public static List<string> GetSubFiles(string argDirectory, int argRecurDepth, bool argRecurPrecedence)
  45. {
  46. var list = new List<string>();
  47. if (string.IsNullOrEmpty(argDirectory)) return list;
  48. var directorylist = new List<string>();
  49. if (argRecurDepth == 0)
  50. {
  51. directorylist.Add(argDirectory);
  52. }
  53. else
  54. {
  55. var recurdicrotylist = GetSubDirectories(argDirectory, argRecurDepth, argRecurPrecedence);
  56. if (argRecurPrecedence)
  57. {
  58. directorylist.AddRange(recurdicrotylist);
  59. directorylist.Add(argDirectory);
  60. }
  61. else
  62. {
  63. directorylist.Add(argDirectory);
  64. directorylist.AddRange(recurdicrotylist);
  65. }
  66. }
  67. foreach (var directory in directorylist)
  68. {
  69. try
  70. {
  71. var files = System.IO.Directory.GetFiles(directory);
  72. list.AddRange(files);
  73. }
  74. catch { }
  75. }
  76. return list;
  77. }
  78. /// <summary>获取指定目录下子目录的路径。</summary>
  79. /// <param name="argDirectory">顶级目录。</param>
  80. /// <param name="argRecurSub">递归子目录。</param>
  81. /// <param name="argRecurPrecedence">优先排列递归项。</param>
  82. public static List<string> GetSubDirectories(string argDirectory, bool argRecurSub, bool argRecurPrecedence)
  83. {
  84. return GetSubDirectories(argDirectory, argRecurSub ? -1 : 0, argRecurPrecedence);
  85. }
  86. /// <summary>获取指定目录下子目录的路径。</summary>
  87. /// <param name="argDirectory">顶级目录。</param>
  88. /// <param name="argRecurDepth">子目录递归深度。</param>
  89. /// <param name="argRecurPrecedence">优先排列递归项。</param>
  90. public static List<string> GetSubDirectories(string argDirectory, int argRecurDepth, bool argRecurPrecedence)
  91. {
  92. var list = new List<string>();
  93. if (string.IsNullOrEmpty(argDirectory)) return list;
  94. var directories = new string[0];
  95. try
  96. {
  97. directories = System.IO.Directory.GetDirectories(argDirectory);
  98. }
  99. catch { }
  100. foreach (var directory in directories)
  101. {
  102. var recurlist = new List<string>();
  103. if (argRecurDepth != 0)
  104. {
  105. var depth = (argRecurDepth > 0) ? argRecurDepth - 1 : argRecurDepth;
  106. var subrecur = GetSubDirectories(directory, depth, argRecurPrecedence);
  107. recurlist.AddRange(subrecur);
  108. }
  109. if (argRecurPrecedence)
  110. {
  111. list.AddRange(recurlist);
  112. list.Add(directory);
  113. }
  114. else
  115. {
  116. list.Add(directory);
  117. list.AddRange(recurlist);
  118. }
  119. }
  120. return list;
  121. }
  122. public static bool DeleteFile(string argPath)
  123. {
  124. if (string.IsNullOrEmpty(argPath)) return false;
  125. if (!PathExists(argPath)) return true;
  126. try
  127. {
  128. if (FileExists(argPath)) System.IO.File.Delete(argPath);
  129. return !PathExists(argPath);
  130. }
  131. catch { return false; }
  132. }
  133. public static bool DeleteDirectory(string argPath, bool argRecursive = true)
  134. {
  135. if (string.IsNullOrEmpty(argPath)) return false;
  136. if (!PathExists(argPath)) return true;
  137. try
  138. {
  139. if (DirectoryExists(argPath)) System.IO.Directory.Delete(argPath, argRecursive);
  140. return !PathExists(argPath);
  141. }
  142. catch { return false; }
  143. }
  144. public static bool DeletePath(string argPath, bool argRecursive = true)
  145. {
  146. if (string.IsNullOrEmpty(argPath)) return false;
  147. if (!PathExists(argPath)) return true;
  148. try
  149. {
  150. if (FileExists(argPath)) System.IO.File.Delete(argPath);
  151. if (DirectoryExists(argPath)) System.IO.Directory.Delete(argPath, argRecursive);
  152. return !PathExists(argPath);
  153. }
  154. catch { return false; }
  155. }
  156. public static bool AssureDirectory(string argPath)
  157. {
  158. if (string.IsNullOrEmpty(argPath)) return false;
  159. try
  160. {
  161. if (System.IO.File.Exists(argPath)) return false;
  162. if (System.IO.Directory.Exists(argPath)) return true;
  163. var created = System.IO.Directory.CreateDirectory(argPath);
  164. return created.Exists;
  165. }
  166. catch { }
  167. return false;
  168. }
  169. public static bool AssureParent(string argFilePath)
  170. {
  171. if (string.IsNullOrEmpty(argFilePath)) return false;
  172. var parent = Constant.EmptyString;
  173. try { parent = System.IO.Directory.GetParent(argFilePath).FullName; } finally { }
  174. var result = AssureDirectory(parent);
  175. return result;
  176. }
  177. /// <summary>获取文件流。若文件不存在,则先创建文件;若获取失败,则返回 NULL 值。</summary>
  178. /// <param name="argPath">文件路径。</param>
  179. /// <param name="argShare">共享。</param>
  180. public static System.IO.FileStream OpenFile(string argPath, bool argShare = false)
  181. {
  182. try
  183. {
  184. if (string.IsNullOrEmpty(argPath)) return null;
  185. if (DirectoryExists(argPath)) return null;
  186. if (AssureParent(argPath))
  187. {
  188. var mode = System.IO.FileMode.OpenOrCreate;
  189. var access = System.IO.FileAccess.ReadWrite;
  190. var share = argShare ? System.IO.FileShare.ReadWrite : System.IO.FileShare.None;
  191. var stream = new System.IO.FileStream(argPath, mode, access, share);
  192. return stream;
  193. }
  194. }
  195. catch { }
  196. return null;
  197. }
  198. /// <summary>创建一个空文件且不保留句柄。</summary>
  199. /// <param name="argPath">文件路径,若已存在则返回失败。</param>
  200. /// <param name="argLength">文件长度(字节数)。</param>
  201. /// <param name="argReplace">替换现有文件。</param>
  202. /// <returns>创建成功。</returns>
  203. public static bool CreateFile(string argPath, long argLength = 0, bool argReplace = false)
  204. {
  205. try
  206. {
  207. if (string.IsNullOrEmpty(argPath)) return false;
  208. if (argReplace) { if (!DeletePath(argPath, true)) return false; }
  209. else { if (PathExists(argPath)) return false; }
  210. var stream = OpenFile(argPath);
  211. if (stream != null)
  212. {
  213. if (argLength > 0)
  214. {
  215. stream.SetLength(argLength);
  216. }
  217. stream.Close();
  218. stream.Dispose();
  219. return true;
  220. }
  221. }
  222. catch { }
  223. return false;
  224. }
  225. /// <summary>向文件写入数据。若写入失败则返回 -1 值。</summary>
  226. public static long WriteFile(string argPath, System.IO.Stream argStream, Action<Int64> argCallback = null)
  227. {
  228. var created = CreateFile(argPath, 0, true);
  229. if (created)
  230. {
  231. var stream = OpenFile(argPath);
  232. var result = 0L;
  233. if (stream != null)
  234. {
  235. result = StreamHelper.Read(argStream, stream, Constant.DefaultBufferCapacity, argCallback);
  236. }
  237. KernelUtility.Dispose(stream);
  238. return result;
  239. }
  240. return -1;
  241. }
  242. /// <summary>向文件写入数据。文件不存在将创建,存在则覆盖。</summary>
  243. public static bool WriteFile(string argPath, byte[] argData)
  244. {
  245. return WriteFile(argPath, false, argData);
  246. }
  247. /// <summary>向文件写入数据。文件不存在将创建,存在则覆盖。</summary>
  248. public static bool WriteFile(string argPath, bool argAddBom, byte[] argData)
  249. {
  250. var created = CreateFile(argPath, 0, true);
  251. if (created)
  252. {
  253. try
  254. {
  255. if (argData == null) return true;
  256. var data = argData;
  257. if (argAddBom) data = ByteHelper.AddTextBom(data);
  258. System.IO.File.WriteAllBytes(argPath, data);
  259. return true;
  260. }
  261. finally { }
  262. }
  263. return false;
  264. }
  265. /// <summary>向文件写入数据。若写入失败则返回 -1 值。</summary>
  266. public static long AppendFile(string argPath, System.IO.Stream argStream, Action<Int64> argCallback = null)
  267. {
  268. var error = -1;
  269. var assured = AssureParent(argPath);
  270. if (assured)
  271. {
  272. var stream = OpenFile(argPath, true);
  273. var result = 0L;
  274. if (stream != null)
  275. {
  276. var failed = false;
  277. try { stream.Position = stream.Length; } catch { failed = true; }
  278. if (!failed)
  279. {
  280. result = StreamHelper.Read(argStream, stream, Constant.DefaultBufferCapacity, argCallback);
  281. }
  282. try { stream.Flush(); } finally { }
  283. }
  284. KernelUtility.Dispose(stream);
  285. return result;
  286. }
  287. return error;
  288. }
  289. /// <summary>向文件追加数据。文件不存在将创建,存在则覆盖。</summary>
  290. public static bool AppendFile(string argPath, params byte[] argData)
  291. {
  292. var assured = AssureParent(argPath);
  293. if (assured)
  294. {
  295. var stream = OpenFile(argPath, true);
  296. var failed = false;
  297. if (stream != null)
  298. {
  299. try
  300. {
  301. stream.Position = stream.Length;
  302. if (argData != null) stream.Write(argData, 0, argData.Length);
  303. }
  304. catch { failed = true; }
  305. KernelUtility.Dispose(stream, true);
  306. }
  307. if (!failed) return true;
  308. }
  309. return false;
  310. }
  311. /// <summary>复制文件。</summary>
  312. /// <param name="argOldPath">旧路径。</param>
  313. /// <param name="argNewPath">新路径。</param>
  314. /// <param name="argReplace">新路劲存在时,替换新文件。</param>
  315. public static bool CopyFile(string argOldPath, string argNewPath, bool argReplace = true)
  316. {
  317. if (string.IsNullOrEmpty(argOldPath)) return false;
  318. if (string.IsNullOrEmpty(argNewPath)) return false;
  319. if (!FileExists(argOldPath)) return false;
  320. try
  321. {
  322. System.IO.File.Copy(argOldPath, argNewPath, argReplace);
  323. return true;
  324. }
  325. catch { return false; }
  326. }
  327. public static byte[] ReadFile(string argFilePath, bool argWipeBom = true, Action<Int64> argCallback = null)
  328. {
  329. if (FileExists(argFilePath))
  330. {
  331. var bytes = null as byte[];
  332. if (argCallback == null)
  333. {
  334. try
  335. {
  336. bytes = System.IO.File.ReadAllBytes(argFilePath);
  337. }
  338. catch { }
  339. }
  340. else
  341. {
  342. var file = null as System.IO.FileStream;
  343. var memory = new System.IO.MemoryStream();
  344. file = OpenFile(argFilePath, true);
  345. StreamHelper.Read(file, memory, Constant.DefaultBufferCapacity, argCallback);
  346. if (file != null) file.Dispose();
  347. bytes = memory.ToArray();
  348. memory.Dispose();
  349. }
  350. if (argWipeBom) bytes = ByteHelper.WipeTextBom(bytes);
  351. return bytes;
  352. }
  353. return Constant.EmptyBytes;
  354. }
  355. public static string FixFileName(string argFileName)
  356. {
  357. var result = argFileName;
  358. if (string.IsNullOrEmpty(result))
  359. {
  360. result = Constant.EmptyString;
  361. }
  362. else
  363. {
  364. result = result.Replace("\"", "");
  365. result = result.Replace("\\", "");
  366. result = result.Replace("/", "");
  367. result = result.Replace(":", "");
  368. result = result.Replace("*", "");
  369. result = result.Replace("?", "");
  370. result = result.Replace("<", "");
  371. result = result.Replace(">", "");
  372. result = result.Replace("|", "");
  373. }
  374. if (result.Length > 0) result = result.Trim();
  375. return result;
  376. }
  377. }
  378. }