using JNPF.Common.Configuration;
using JNPF.Common.Extension;
using JNPF.Common.Models;
using JNPF.DependencyInjection;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Web;
namespace JNPF.Common.Security;
///
/// FileHelper
/// 版 本:V3.2.0
/// 版 权:拓通智联科技有限公司(http://www.tuotong-tech.com)
/// 作 者:JNPF开发平台组.
///
[SuppressSniffer]
public class FileHelper
{
#region 返回绝对路径
///
/// 返回绝对路径.
///
/// 相对路径.
///
public static string GetAbsolutePath(string filePath)
{
return Directory.GetCurrentDirectory() + filePath;
}
#endregion
#region 检测指定目录是否存在
///
/// 检测指定目录是否存在.
///
/// 目录的绝对路径
///
public static bool IsExistDirectory(string directoryPath)
{
return Directory.Exists(directoryPath);
}
#endregion
#region 检测指定文件是否存在,如果存在返回true
///
/// 检测指定文件是否存在,如果存在则返回true.
///
/// 文件的绝对路径.
public static bool IsExistFile(string filePath)
{
return File.Exists(filePath);
}
///
/// 检测指定文件是否存在,如果存在则返回true.
///
/// 文件的绝对路径.
public static bool Exists(string filePath)
{
return File.Exists(filePath);
}
#endregion
#region 获取指定目录中的文件列表
///
/// 获取指定目录中所有文件列表.
///
/// 指定目录的绝对路径.
public static string[] GetFileNames(string directoryPath)
{
// 如果目录不存在,则抛出异常
if (!IsExistDirectory(directoryPath))
throw new FileNotFoundException();
return Directory.GetFiles(directoryPath);
}
///
/// 获取指定目录中所有文件列表.
///
/// 指定目录的绝对路径.
/// 返回文件.
///
public static List GetAllFiles(string directoryPath, List? data = null)
{
if (!IsExistDirectory(directoryPath))
return new List();
List listFiles = data == null ? new List() : data;
DirectoryInfo directory = new DirectoryInfo(directoryPath);
DirectoryInfo[] directorys = directory.GetDirectories();
FileInfo[] fileInfos = directory.GetFiles();
if (fileInfos.Length > 0)
listFiles.AddRange(fileInfos);
foreach (DirectoryInfo itemDirectory in directorys)
{
GetAllFiles(itemDirectory.FullName, listFiles);
}
return listFiles;
}
#endregion
#region 获取指定目录中所有子目录列表,若要搜索嵌套的子目录列表,请使用重载方法.
///
/// 获取指定目录中所有子目录列表,若要搜索嵌套的子目录列表,请使用重载方法.
///
/// 指定目录的绝对路径.
public static string[] GetDirectories(string directoryPath)
{
try
{
return Directory.GetDirectories(directoryPath);
}
catch (IOException)
{
throw;
}
}
#endregion
#region 获取指定目录及子目录中所有文件列表
///
/// 获取指定目录及子目录中所有文件列表.
///
/// 指定目录的绝对路径.
/// 模式字符串,"*"代表0或N个字符,"?"代表1个字符
/// 范例:"Log*.xml"表示搜索所有以Log开头的Xml文件.
/// 是否搜索子目录.
public static string[] GetFileNames(string directoryPath, string searchPattern, bool isSearchChild)
{
// 如果目录不存在,则抛出异常
if (!IsExistDirectory(directoryPath))
throw new FileNotFoundException();
try
{
if (isSearchChild)
return Directory.GetFiles(directoryPath, searchPattern, SearchOption.AllDirectories);
else
return Directory.GetFiles(directoryPath, searchPattern, SearchOption.TopDirectoryOnly);
}
catch (IOException)
{
throw;
}
}
#endregion
#region 创建目录
///
/// 创建目录.
///
/// 要创建的目录路径包括目录名.
public static void CreateDir(string dir)
{
if (dir.Length == 0) return;
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
}
#endregion
#region 删除目录
///
/// 删除指定目录及其所有子目录.
///
/// 要删除的目录路径和名称.
public static void DeleteDirectory(string dir)
{
if (dir.Length == 0) return;
if (Directory.Exists(dir))
Directory.Delete(dir, true);
}
#endregion
#region 删除文件
///
/// 删除文件.
///
/// 要删除的文件路径和名称.
public static void DeleteFile(string file)
{
if (File.Exists(file))
File.Delete(file);
}
///
/// 删除文件.
///
/// 要删除的文件路径和名称.
public static void Delete(string file)
{
if (File.Exists(file))
File.Delete(file);
}
#endregion
#region 创建文件
///
/// 创建文件.
///
/// 带后缀的文件名.
/// 文件内容.
public static void CreateFile(string dir, string content)
{
dir = dir.Replace("/", "\\");
if (dir.IndexOf("\\") > -1)
CreateDir(dir.Substring(0, dir.LastIndexOf("\\")));
StreamWriter sw = new StreamWriter(dir, false);
sw.Write(content);
sw.Close();
sw.Dispose();
}
///
/// 创建文件.
///
/// 文件的绝对路径.
public static void CreateFile(string filePath)
{
if (!IsExistFile(filePath))
{
FileInfo file = new FileInfo(filePath);
FileStream fs = file.Create();
fs.Close();
}
}
///
/// 创建文件,并将字节流写入文件.
///
/// 文件的绝对路径.
/// 二进制流数据.
public static void CreateFile(string filePath, byte[] buffer)
{
if (!IsExistFile(filePath))
{
FileInfo file = new FileInfo(filePath);
FileStream fs = file.Create();
fs.Write(buffer, 0, buffer.Length);
fs.Close();
}
}
#endregion
#region 移动文件
///
/// 移动文件(剪贴--粘贴).
///
/// 要移动的文件的路径及全名(包括后缀).
/// 文件移动到新的位置,并指定新的文件名.
public static void MoveFile(string dir1, string dir2)
{
if (File.Exists(dir1))
File.Move(dir1, dir2);
}
#endregion
#region 复制文件
///
/// 复制文件.
///
/// 要复制的文件的路径已经全名(包括后缀).
/// 目标位置,并指定新的文件名.
public static void CopyFile(string dir1, string dir2)
{
if (File.Exists(dir1))
File.Copy(dir1, dir2);
}
#endregion
#region 复制文件夹
///
/// 复制文件夹(递归).
///
/// 源文件夹路径.
/// 目标文件夹路径.
public static void CopyFolder(string varFromDirectory, string varToDirectory)
{
Directory.CreateDirectory(varToDirectory);
if (!Directory.Exists(varFromDirectory)) return;
string[] directories = Directory.GetDirectories(varFromDirectory);
if (directories.Length > 0)
{
foreach (string d in directories)
{
CopyFolder(d, varToDirectory + d.Substring(d.LastIndexOf("\\")));
}
}
string[] files = Directory.GetFiles(varFromDirectory);
if (files.Length > 0)
{
foreach (string s in files)
{
File.Copy(s, varToDirectory + s.Substring(s.LastIndexOf("\\")), true);
}
}
}
#endregion
#region 删除指定文件夹对应其他文件夹里的文件
///
/// 删除指定文件夹对应其他文件夹里的文件.
///
/// 指定文件夹路径.
/// 对应其他文件夹路径.
public static void DeleteFolderFiles(string varFromDirectory, string varToDirectory)
{
Directory.CreateDirectory(varToDirectory);
if (!Directory.Exists(varFromDirectory)) return;
string[] directories = Directory.GetDirectories(varFromDirectory);
if (directories.Length > 0)
{
foreach (string d in directories)
{
DeleteFolderFiles(d, varToDirectory + d.Substring(d.LastIndexOf("\\")));
}
}
string[] files = Directory.GetFiles(varFromDirectory);
if (files.Length > 0)
{
foreach (string s in files)
{
File.Delete(varToDirectory + s.Substring(s.LastIndexOf("\\")));
}
}
}
#endregion
#region 从文件的绝对路径中获取文件名( 包含扩展名 )
///
/// 从文件的绝对路径中获取文件名( 包含扩展名 ).
///
/// 文件的绝对路径.
public static string GetFileName(string filePath)
{
// 获取文件的名称
FileInfo fi = new FileInfo(filePath);
return fi.Name;
}
#endregion
#region 获取一个文件的长度
///
/// 获取一个文件的长度,单位为Byte.
///
/// 文件的绝对路径.
public static long GetFileSize(string filePath)
{
FileInfo fi = new FileInfo(filePath);
return fi.Length;
}
#endregion
#region 获取文件大小并以B,KB,GB,TB
///
/// 计算文件大小函数(保留两位小数),Size为字节大小.
///
/// 初始文件大小.
///
public static string ToFileSize(long size)
{
string m_strSize = string.Empty;
long factSize = 0;
factSize = size;
if (factSize < 1024.00)
m_strSize = factSize.ToString("F2") + " 字节";
else if (factSize >= 1024.00 && factSize < 1048576)
m_strSize = (factSize / 1024.00).ToString("F2") + " KB";
else if (factSize >= 1048576 && factSize < 1073741824)
m_strSize = (factSize / 1024.00 / 1024.00).ToString("F2") + " MB";
else if (factSize >= 1073741824)
m_strSize = (factSize / 1024.00 / 1024.00 / 1024.00).ToString("F2") + " GB";
return m_strSize;
}
#endregion
#region 将现有文件的内容复制到新文件中
///
/// 将源文件的内容复制到目标文件中.
///
/// 源文件的绝对路径.
/// 目标文件的绝对路径.
public static void Copy(string sourceFilePath, string destFilePath)
{
File.Copy(sourceFilePath, destFilePath, true);
}
#endregion
#region ReadAllBytes
///
/// ReadAllBytes.
///
/// path.
///
public static byte[]? ReadAllBytes(string path)
{
try
{
return File.ReadAllBytes(path);
}
catch (Exception)
{
return null;
}
}
///
/// 读取全部字符串.
///
///
///
public static string? ReadAllStr(string path)
{
string line = string.Empty;
FileStream fileStream = new FileStream(path, FileMode.Open);
using (StreamReader reader = new StreamReader(fileStream))
{
line = reader.ReadLine();
}
return line;
}
#endregion
#region 将文件读取到字符串中
///
/// 将文件读取到字符串中.
///
/// 文件的绝对路径.
public static string FileToString(string filePath)
{
return FileToString(filePath, Encoding.UTF8);
}
///
/// 将文件读取到字符串中.
///
/// 文件的绝对路径.
/// 字符编码
public static string FileToString(string filePath, Encoding encoding)
{
// 创建流读取器
StreamReader reader = new StreamReader(filePath, encoding);
try
{
// 读取流
return reader.ReadToEnd();
}
catch (Exception ex)
{
throw ex;
}
finally
{
// 关闭流读取器
reader.Close();
}
}
#endregion
#region 生成高清晰缩略图
///
/// 根据源图片生成高清晰缩略图.
///
/// 源图(大图)物理路径.
/// 缩略图物理路径(生成的缩略图将保存到该物理位置).
/// 缩略图宽度.
/// 缩略图高度.
/// 缩略图缩放模式(取值"HW":指定高宽缩放,可能变形;取值"W":按指定宽度,高度按比例缩放;取值"H":按指定高度,宽度按比例缩放;取值"Cut":按指定高度和宽度裁剪,不变形);取值"DB":等比缩放,以值较大的作为标准进行等比缩放.
/// 即将生成缩略图的文件的扩展名(仅限:JPG、GIF、PNG、BMP).
public static void MakeThumbnail(string imgPath_old, string imgPath_new, int width, int height, string mode, string imageType, int xx, int yy)
{
if (IsExistFile(imgPath_old))
{
Image img = Image.FromFile(imgPath_old);
int towidth = width;
int toheight = height;
int x = 0;
int y = 0;
int ow = img.Width;
int oh = img.Height;
switch (mode)
{
// 指定高宽压缩
case "HW":
// 判断图形是什么形状
if ((double)img.Width / (double)img.Height > (double)width / (double)height)
{
towidth = width;
toheight = img.Height * width / img.Width;
}
else if ((double)img.Width / (double)img.Height == (double)width / (double)height)
{
towidth = width;
toheight = height;
}
else
{
toheight = height;
towidth = img.Width * height / img.Height;
}
break;
case "W":
// 指定宽,高按比例
toheight = img.Height * width / img.Width;
break;
case "H":
// 指定高,宽按比例
towidth = img.Width * height / img.Height;
break;
case "Cut":
// 指定高宽裁减(不变形)
if ((double)img.Width / (double)img.Height > (double)towidth / (double)toheight)
{
oh = img.Height;
ow = img.Height * towidth / toheight;
y = yy;
x = (img.Width - ow) / 2;
}
else
{
ow = img.Width;
oh = img.Width * height / towidth;
x = xx;
y = (img.Height - oh) / 2;
}
break;
case "DB":
// 按值较大的进行等比缩放(不变形)
if ((double)img.Width / (double)towidth < (double)img.Height / (double)toheight)
{
toheight = height;
towidth = img.Width * height / img.Height;
}
else
{
towidth = width;
toheight = img.Height * width / img.Width;
}
break;
default:
break;
}
// 新建一个bmp图片
Image bitmap = new Bitmap(towidth, toheight);
// 新建一个画板
Graphics g = Graphics.FromImage(bitmap);
// 设置高质量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
// 设置高质量,低速度呈现平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
// 清空画布并以透明背景色填充
g.Clear(Color.Transparent);
// 在指定位置并且按指定大小绘制原图片的指定部分
g.DrawImage(img, new Rectangle(0, 0, towidth, toheight), new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel);
try
{
// 以jpg格式保存缩略图
switch (imageType.ToLower())
{
case "gif":
// 生成缩略图
bitmap.Save(imgPath_new, ImageFormat.Gif);
break;
case "jpg":
bitmap.Save(imgPath_new, ImageFormat.Jpeg);
break;
case "bmp":
bitmap.Save(imgPath_new, ImageFormat.Bmp);
break;
case "png":
bitmap.Save(imgPath_new, ImageFormat.Png);
break;
default:
bitmap.Save(imgPath_new, ImageFormat.Jpeg);
break;
}
bitmap.Save(imgPath_new);
}
catch (Exception)
{
throw;
}
finally
{
img.Dispose();
bitmap.Dispose();
g.Dispose();
}
}
}
#endregion
#region 获取文件类型
///
/// 获取文件类型.
///
/// 文件
///
public static string? GetFileType(FileInfo file)
{
if (file.Exists)
{
string fileName = file.Name;
return fileName.Substring(fileName.LastIndexOf(".") + 1);
}
return string.Empty;
}
#endregion
#region 将文件路径转为内存流
///
/// 将文件路径转为内存流.
///
///
///
public static MemoryStream FileToStream(string fileName)
{
// 打开文件
FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
// 读取文件的 byte[]
byte[] bytes = new byte[fileStream.Length];
fileStream.Read(bytes, 0, bytes.Length);
fileStream.Close();
// 把 byte[] 转换成 Stream
return new MemoryStream(bytes);
}
#endregion
#region 根据文件大小获取指定前缀的可用文件名
///
/// 根据文件大小获取指定前缀的可用文件名.
///
/// 文件夹.
/// 文件前缀.
/// 文件大小(1m).
/// 文件后缀(.log).
/// 可用文件名.
public static string GetAvailableFileWithPrefixOrderSize(string folderPath, string prefix, int size = 1 * 1024 * 1024, string ext = ".log")
{
DirectoryInfo allFiles = new DirectoryInfo(folderPath);
List selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(prefix.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d => d.Name).ToList();
if (selectFiles.Count > 0)
{
return selectFiles.FirstOrDefault().FullName;
}
return Path.Combine(folderPath, $@"{prefix}_{DateTime.Now.ParseToUnixTime()}.log");
}
#endregion
#region 文件下载
///
/// 普通下载.
///
/// 路径.
/// 文件名.
public static void DownloadFile(string filePath, string fileName)
{
try
{
if (File.Exists(filePath))
{
byte[]? buff = ReadAllBytes(filePath);
Microsoft.AspNetCore.Http.HttpContext? httpContext = App.HttpContext;
httpContext.Response.ContentType = "application/octet-stream";
httpContext.Response.Headers.Add("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
httpContext.Response.Headers.Add("Content-Length", buff.Length.ToString());
httpContext.Response.Body.WriteAsync(buff);
httpContext.Response.Body.Flush();
httpContext.Response.Body.Close();
}
}
catch (Exception)
{
}
}
///
/// 普通下载.
///
/// 文件流.
/// 文件名.
public static void DownloadFile(byte[] buffer, string fileName)
{
Microsoft.AspNetCore.Http.HttpContext? httpContext = App.HttpContext;
httpContext.Response.ContentType = "application/octet-stream";
httpContext.Response.Headers.Add("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
httpContext.Response.Body.Write(buffer);
httpContext.Response.Body.Flush();
httpContext.Response.Body.Close();
}
#endregion
#region 附件处理
///
/// 添加附件:将临时文件夹的文件拷贝到正式文件夹里面.
///
///
public static void CreateFile(List data)
{
if (data != null && data.Count > 0)
{
string temporaryFilePath = Path.Combine(KeyVariable.SystemPath, "TemporaryFile");
string systemFilePath = KeyVariable.SystemPath;
foreach (AnnexModel item in data)
{
MoveFile(temporaryFilePath + item.FileId, systemFilePath + item.FileId);
}
}
}
///
/// 更新附件.
///
///
public static void UpdateFile(List data)
{
if (data != null)
{
string temporaryFilePath = Path.Combine(KeyVariable.SystemPath, "TemporaryFile");
string systemFilePath = KeyVariable.SystemPath;
foreach (AnnexModel item in data)
{
if (item.FileType == "add")
{
MoveFile(temporaryFilePath + item.FileId, systemFilePath + item.FileId);
}
else if (item.FileType == "delete")
{
DeleteFile(systemFilePath + item.FileId);
}
}
}
}
///
/// 删除附件.
///
///
public static void DeleteFile(List data)
{
if (data != null && data.Count > 0)
{
string systemFilePath = KeyVariable.SystemPath;
foreach (AnnexModel item in data)
{
DeleteFile(systemFilePath + item.FileId);
}
}
}
#endregion
}