luban/src/Luban.Common/Source/Utils/FileUtil.cs

198 lines
6.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Common.Utils
{
public static class FileUtil
{
private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger();
public static string GetApplicationDirectory()
{
return Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().Location);
}
public static string GetPathRelateApplicationDirectory(string relatePath)
{
return Path.Combine(GetApplicationDirectory(), relatePath);
}
public static string GetFileName(string path)
{
int index = path.Replace('\\', '/').LastIndexOf('/');
return index >= 0 ? path[(index + 1)..] : path;
}
public static string GetParent(string path)
{
int index = path.Replace('\\', '/').LastIndexOf('/');
return index >= 0 ? path[..index] : ".";
}
public static string GetFileNameWithoutExt(string file)
{
int index = file.LastIndexOf('.');
return index >= 0 ? file.Substring(0, index) : file;
}
public static string GetFileExtension(string file)
{
int index = file.LastIndexOf('.');
return index >= 0 ? file.Substring(index + 1) : "";
}
public static string GetPathRelateRootFile(string rootFile, string file)
{
return Combine(GetParent(rootFile), file);
}
/// <summary>
/// 忽略以 文件名以 '.' '_' '~' 开头的文件
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
public static bool IsValidInputFile(string file)
{
if (!File.Exists(file))
{
return false;
}
var f = new FileInfo(file);
string fname = f.Name;
return !fname.StartsWith('.') && !fname.StartsWith('_') && !fname.StartsWith('~');
}
public static string CalcMD5(byte[] srcBytes)
{
using MD5 md5 = MD5.Create();
var md5Bytes = md5.ComputeHash(srcBytes);
var s = new StringBuilder(md5Bytes.Length * 2);
foreach (var b in md5Bytes)
{
s.Append(b.ToString("X"));
}
return s.ToString();
}
public static string Standardize(string path)
{
return path.Replace('\\', '/');
}
public static string Combine(string parent, string sub)
{
return Standardize(Path.Combine(parent, sub));
}
public static bool IsExcelFile(string fullName)
{
return fullName.EndsWith(".csv", StringComparison.Ordinal)
|| fullName.EndsWith(".xls", StringComparison.Ordinal)
|| fullName.EndsWith(".xlsx", StringComparison.Ordinal);
}
public static (string, string) SplitFileAndSheetName(string url)
{
int sheetSepIndex = url.IndexOf('@');
if (sheetSepIndex < 0)
{
return (url, null);
}
else
{
int lastPathSep = url.LastIndexOf('/', sheetSepIndex);
if (lastPathSep >= 0)
{
return (url[0..(lastPathSep + 1)] + url[(sheetSepIndex + 1)..], url[(lastPathSep + 1)..sheetSepIndex]);
}
else
{
return (url[(sheetSepIndex + 1)..], url[(lastPathSep + 1)..sheetSepIndex]);
}
}
}
public static async Task SaveFileAsync(string relateDir, string filePath, byte[] content)
{
// 调用此接口时,已保证 文件必然是改变的,不用再检查对比文件
var outputPath = Standardize(relateDir != null ? System.IO.Path.Combine(relateDir, filePath) : filePath);
Directory.GetParent(outputPath).Create();
if (File.Exists(outputPath))
{
s_logger.Info("[override] {file}", outputPath);
if (File.GetAttributes(outputPath).HasFlag(FileAttributes.ReadOnly))
{
File.SetAttributes(outputPath, FileAttributes.Normal);
}
}
else
{
s_logger.Info("[new] {file}", outputPath);
}
await WriteAllBytesAsync(outputPath, content);
}
public static async Task<byte[]> ReadAllBytesAsync(string file)
{
// File.ReadAllBytesAsync 无法读取被打开的excel文件只好重新实现了一个
using var fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
long count = fs.Length;
var bytes = new byte[count];
int writeIndex = 0;
while (writeIndex < count)
{
int n = await fs.ReadAsync(bytes, writeIndex, (int)count - writeIndex, default);
writeIndex += n;
}
return bytes;
}
public static byte[] ReadAllBytes(string file)
{
// File.ReadAllBytesAsync 无法读取被打开的excel文件只好重新实现了一个
using var fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
long count = fs.Length;
var bytes = new byte[count];
int writeIndex = 0;
while (writeIndex < count)
{
int n = fs.Read(bytes, writeIndex, (int)count - writeIndex);
writeIndex += n;
}
return bytes;
}
public static async Task WriteAllBytesAsync(string file, byte[] bytes)
{
using var fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
long count = bytes.LongLength;
fs.SetLength(count);
fs.Seek(0, SeekOrigin.Begin);
await fs.WriteAsync(bytes);
}
public static void DeleteDirectoryRecursive(string rootDir)
{
string[] files = Directory.GetFiles(rootDir);
string[] dirs = Directory.GetDirectories(rootDir);
foreach (string file in files)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
foreach (string dir in dirs)
{
DeleteDirectoryRecursive(dir);
}
Directory.Delete(rootDir, false);
}
}
}