using Apewer; using System; using System.Collections.Generic; using System.Text; namespace Apewer.Internals { internal class StorageHelper { public static bool FileExists(string argPath) { if (string.IsNullOrEmpty(argPath)) return false; return System.IO.File.Exists(argPath); } public static bool DirectoryExists(string argPath) { if (string.IsNullOrEmpty(argPath)) return false; return System.IO.Directory.Exists(argPath); } public static bool PathExists(string argPath) { if (string.IsNullOrEmpty(argPath)) return false; if (System.IO.File.Exists(argPath)) return true; if (System.IO.Directory.Exists(argPath)) return true; return false; } /// 获取指定目录下子文件的路径,不递归子目录。 /// 顶级目录。 public static List GetSubFiles(string argDirectory) { return GetSubFiles(argDirectory, false, false); } /// 获取指定目录下子文件的路径。 /// 顶级目录。 /// 递归子目录。 /// 优先排列递归项。 public static List GetSubFiles(string argDirectory, bool argRecurSub, bool argRecurPrecedence) { return GetSubFiles(argDirectory, argRecurSub ? -1 : 0, argRecurPrecedence); } /// 获取指定目录下子文件的路径。 /// 顶级目录。 /// 子目录递归深度。 /// 优先排列递归项。 public static List GetSubFiles(string argDirectory, int argRecurDepth, bool argRecurPrecedence) { var list = new List(); if (string.IsNullOrEmpty(argDirectory)) return list; var directorylist = new List(); if (argRecurDepth == 0) { directorylist.Add(argDirectory); } else { var recurdicrotylist = GetSubDirectories(argDirectory, argRecurDepth, argRecurPrecedence); if (argRecurPrecedence) { directorylist.AddRange(recurdicrotylist); directorylist.Add(argDirectory); } else { directorylist.Add(argDirectory); directorylist.AddRange(recurdicrotylist); } } foreach (var directory in directorylist) { try { var files = System.IO.Directory.GetFiles(directory); list.AddRange(files); } catch { } } return list; } /// 获取指定目录下子目录的路径。 /// 顶级目录。 /// 递归子目录。 /// 优先排列递归项。 public static List GetSubDirectories(string argDirectory, bool argRecurSub, bool argRecurPrecedence) { return GetSubDirectories(argDirectory, argRecurSub ? -1 : 0, argRecurPrecedence); } /// 获取指定目录下子目录的路径。 /// 顶级目录。 /// 子目录递归深度。 /// 优先排列递归项。 public static List GetSubDirectories(string argDirectory, int argRecurDepth, bool argRecurPrecedence) { var list = new List(); if (string.IsNullOrEmpty(argDirectory)) return list; var directories = new string[0]; try { directories = System.IO.Directory.GetDirectories(argDirectory); } catch { } foreach (var directory in directories) { var recurlist = new List(); if (argRecurDepth != 0) { var depth = (argRecurDepth > 0) ? argRecurDepth - 1 : argRecurDepth; var subrecur = GetSubDirectories(directory, depth, argRecurPrecedence); recurlist.AddRange(subrecur); } if (argRecurPrecedence) { list.AddRange(recurlist); list.Add(directory); } else { list.Add(directory); list.AddRange(recurlist); } } return list; } public static bool DeleteFile(string argPath) { if (string.IsNullOrEmpty(argPath)) return false; if (!PathExists(argPath)) return true; try { if (FileExists(argPath)) System.IO.File.Delete(argPath); return !PathExists(argPath); } catch { return false; } } public static bool DeleteDirectory(string argPath, bool argRecursive = true) { if (string.IsNullOrEmpty(argPath)) return false; if (!PathExists(argPath)) return true; try { if (DirectoryExists(argPath)) System.IO.Directory.Delete(argPath, argRecursive); return !PathExists(argPath); } catch { return false; } } public static bool DeletePath(string argPath, bool argRecursive = true) { if (string.IsNullOrEmpty(argPath)) return false; if (!PathExists(argPath)) return true; try { if (FileExists(argPath)) System.IO.File.Delete(argPath); if (DirectoryExists(argPath)) System.IO.Directory.Delete(argPath, argRecursive); return !PathExists(argPath); } catch { return false; } } public static bool AssureDirectory(string argPath) { if (string.IsNullOrEmpty(argPath)) return false; try { if (System.IO.File.Exists(argPath)) return false; if (System.IO.Directory.Exists(argPath)) return true; var created = System.IO.Directory.CreateDirectory(argPath); return created.Exists; } catch { } return false; } public static bool AssureParent(string argFilePath) { if (string.IsNullOrEmpty(argFilePath)) return false; var parent = Constant.EmptyString; try { parent = System.IO.Directory.GetParent(argFilePath).FullName; } finally { } var result = AssureDirectory(parent); return result; } /// 获取文件流。若文件不存在,则先创建文件;若获取失败,则返回 NULL 值。 /// 文件路径。 /// 共享。 public static System.IO.FileStream OpenFile(string argPath, bool argShare = false) { try { if (string.IsNullOrEmpty(argPath)) return null; if (DirectoryExists(argPath)) return null; if (AssureParent(argPath)) { var mode = System.IO.FileMode.OpenOrCreate; var access = System.IO.FileAccess.ReadWrite; var share = argShare ? System.IO.FileShare.ReadWrite : System.IO.FileShare.None; var stream = new System.IO.FileStream(argPath, mode, access, share); return stream; } } catch { } return null; } /// 创建一个空文件且不保留句柄。 /// 文件路径,若已存在则返回失败。 /// 文件长度(字节数)。 /// 替换现有文件。 /// 创建成功。 public static bool CreateFile(string argPath, long argLength = 0, bool argReplace = false) { try { if (string.IsNullOrEmpty(argPath)) return false; if (argReplace) { if (!DeletePath(argPath, true)) return false; } else { if (PathExists(argPath)) return false; } var stream = OpenFile(argPath); if (stream != null) { if (argLength > 0) { stream.SetLength(argLength); } stream.Close(); stream.Dispose(); return true; } } catch { } return false; } /// 向文件写入数据。若写入失败则返回 -1 值。 public static long WriteFile(string argPath, System.IO.Stream argStream, Action argCallback = null) { var created = CreateFile(argPath, 0, true); if (created) { var stream = OpenFile(argPath); var result = 0L; if (stream != null) { result = StreamHelper.Read(argStream, stream, Constant.DefaultBufferCapacity, argCallback); } KernelUtility.Dispose(stream); return result; } return -1; } /// 向文件写入数据。文件不存在将创建,存在则覆盖。 public static bool WriteFile(string argPath, byte[] argData) { return WriteFile(argPath, false, argData); } /// 向文件写入数据。文件不存在将创建,存在则覆盖。 public static bool WriteFile(string argPath, bool argAddBom, byte[] argData) { var created = CreateFile(argPath, 0, true); if (created) { try { if (argData == null) return true; var data = argData; if (argAddBom) data = ByteHelper.AddTextBom(data); System.IO.File.WriteAllBytes(argPath, data); return true; } finally { } } return false; } /// 向文件写入数据。若写入失败则返回 -1 值。 public static long AppendFile(string argPath, System.IO.Stream argStream, Action argCallback = null) { var error = -1; var assured = AssureParent(argPath); if (assured) { var stream = OpenFile(argPath, true); var result = 0L; if (stream != null) { var failed = false; try { stream.Position = stream.Length; } catch { failed = true; } if (!failed) { result = StreamHelper.Read(argStream, stream, Constant.DefaultBufferCapacity, argCallback); } try { stream.Flush(); } finally { } } KernelUtility.Dispose(stream); return result; } return error; } /// 向文件追加数据。文件不存在将创建,存在则覆盖。 public static bool AppendFile(string argPath, params byte[] argData) { var assured = AssureParent(argPath); if (assured) { var stream = OpenFile(argPath, true); var failed = false; if (stream != null) { try { stream.Position = stream.Length; if (argData != null) stream.Write(argData, 0, argData.Length); } catch { failed = true; } KernelUtility.Dispose(stream, true); } if (!failed) return true; } return false; } /// 复制文件。 /// 旧路径。 /// 新路径。 /// 新路劲存在时,替换新文件。 public static bool CopyFile(string argOldPath, string argNewPath, bool argReplace = true) { if (string.IsNullOrEmpty(argOldPath)) return false; if (string.IsNullOrEmpty(argNewPath)) return false; if (!FileExists(argOldPath)) return false; try { System.IO.File.Copy(argOldPath, argNewPath, argReplace); return true; } catch { return false; } } public static byte[] ReadFile(string argFilePath, bool argWipeBom = true, Action argCallback = null) { if (FileExists(argFilePath)) { var bytes = null as byte[]; if (argCallback == null) { try { bytes = System.IO.File.ReadAllBytes(argFilePath); } catch { } } else { var file = null as System.IO.FileStream; var memory = new System.IO.MemoryStream(); file = OpenFile(argFilePath, true); StreamHelper.Read(file, memory, Constant.DefaultBufferCapacity, argCallback); if (file != null) file.Dispose(); bytes = memory.ToArray(); memory.Dispose(); } if (argWipeBom) bytes = ByteHelper.WipeTextBom(bytes); return bytes; } return Constant.EmptyBytes; } public static string FixFileName(string argFileName) { var result = argFileName; if (string.IsNullOrEmpty(result)) { result = Constant.EmptyString; } else { result = result.Replace("\"", ""); result = result.Replace("\\", ""); result = result.Replace("/", ""); result = result.Replace(":", ""); result = result.Replace("*", ""); result = result.Replace("?", ""); result = result.Replace("<", ""); result = result.Replace(">", ""); result = result.Replace("|", ""); } if (result.Length > 0) result = result.Trim(); return result; } } }