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
417 lines
15 KiB
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;
|
|
}
|
|
|
|
/// <summary>获取指定目录下子文件的路径,不递归子目录。</summary>
|
|
/// <param name="argDirectory">顶级目录。</param>
|
|
public static List<string> GetSubFiles(string argDirectory)
|
|
{
|
|
return GetSubFiles(argDirectory, false, false);
|
|
}
|
|
|
|
/// <summary>获取指定目录下子文件的路径。</summary>
|
|
/// <param name="argDirectory">顶级目录。</param>
|
|
/// <param name="argRecurSub">递归子目录。</param>
|
|
/// <param name="argRecurPrecedence">优先排列递归项。</param>
|
|
public static List<string> GetSubFiles(string argDirectory, bool argRecurSub, bool argRecurPrecedence)
|
|
{
|
|
return GetSubFiles(argDirectory, argRecurSub ? -1 : 0, argRecurPrecedence);
|
|
}
|
|
|
|
/// <summary>获取指定目录下子文件的路径。</summary>
|
|
/// <param name="argDirectory">顶级目录。</param>
|
|
/// <param name="argRecurDepth">子目录递归深度。</param>
|
|
/// <param name="argRecurPrecedence">优先排列递归项。</param>
|
|
public static List<string> GetSubFiles(string argDirectory, int argRecurDepth, bool argRecurPrecedence)
|
|
{
|
|
var list = new List<string>();
|
|
if (string.IsNullOrEmpty(argDirectory)) return list;
|
|
|
|
var directorylist = new List<string>();
|
|
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;
|
|
}
|
|
|
|
/// <summary>获取指定目录下子目录的路径。</summary>
|
|
/// <param name="argDirectory">顶级目录。</param>
|
|
/// <param name="argRecurSub">递归子目录。</param>
|
|
/// <param name="argRecurPrecedence">优先排列递归项。</param>
|
|
public static List<string> GetSubDirectories(string argDirectory, bool argRecurSub, bool argRecurPrecedence)
|
|
{
|
|
return GetSubDirectories(argDirectory, argRecurSub ? -1 : 0, argRecurPrecedence);
|
|
}
|
|
|
|
/// <summary>获取指定目录下子目录的路径。</summary>
|
|
/// <param name="argDirectory">顶级目录。</param>
|
|
/// <param name="argRecurDepth">子目录递归深度。</param>
|
|
/// <param name="argRecurPrecedence">优先排列递归项。</param>
|
|
public static List<string> GetSubDirectories(string argDirectory, int argRecurDepth, bool argRecurPrecedence)
|
|
{
|
|
var list = new List<string>();
|
|
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<string>();
|
|
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;
|
|
}
|
|
|
|
/// <summary>获取文件流。若文件不存在,则先创建文件;若获取失败,则返回 NULL 值。</summary>
|
|
/// <param name="argPath">文件路径。</param>
|
|
/// <param name="argShare">共享。</param>
|
|
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;
|
|
}
|
|
|
|
/// <summary>创建一个空文件且不保留句柄。</summary>
|
|
/// <param name="argPath">文件路径,若已存在则返回失败。</param>
|
|
/// <param name="argLength">文件长度(字节数)。</param>
|
|
/// <param name="argReplace">替换现有文件。</param>
|
|
/// <returns>创建成功。</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>向文件写入数据。若写入失败则返回 -1 值。</summary>
|
|
public static long WriteFile(string argPath, System.IO.Stream argStream, Action<Int64> 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;
|
|
}
|
|
|
|
/// <summary>向文件写入数据。文件不存在将创建,存在则覆盖。</summary>
|
|
public static bool WriteFile(string argPath, byte[] argData)
|
|
{
|
|
return WriteFile(argPath, false, argData);
|
|
}
|
|
|
|
/// <summary>向文件写入数据。文件不存在将创建,存在则覆盖。</summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>向文件写入数据。若写入失败则返回 -1 值。</summary>
|
|
public static long AppendFile(string argPath, System.IO.Stream argStream, Action<Int64> 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;
|
|
}
|
|
|
|
/// <summary>向文件追加数据。文件不存在将创建,存在则覆盖。</summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>复制文件。</summary>
|
|
/// <param name="argOldPath">旧路径。</param>
|
|
/// <param name="argNewPath">新路径。</param>
|
|
/// <param name="argReplace">新路劲存在时,替换新文件。</param>
|
|
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<Int64> 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;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|