【无私分享:ASP.NET CORE 项目实战(第七章)】文件操作 FileHelper
目录索引
简介
在程序设计中,我们很多情况下,会用到对文件的操作,在 上一个系列 中,我们有很多文件基本操作的示例,在Core中有一些改变,主要是我们常用的Server.MapPath()不存在了,不知道后续的版本会不会有,在这里,我们只能自己封装方法去实现。今天,我们就对一些基本的操作写了一个 FileHelper 类,供大家探讨。在此要感谢以为不愿意透漏姓名的大神的帮助:@YINYEJUN
获取文件的绝对路径
在以前的操作中,这个应该是十分简单的,可以通过 System.Web.HttpContext.Current.Server.MapPath("...") 直接获取,简介中,我们讲过,这个方法已经不存在了,网上翻阅了很多资料,Server.MapPath 最终调用 HostingEnvironment.MapPath() ,但是,它创建了一个特定选项的 virtualpath 对象,我们暂时先不管这些原理性的东西,我们看下如何去实现。
我们这里需要用到 IHostingEnvironment ,注入的方式有很多,最推荐的是 构造器 的注入,例如:
public readonly IHostingEnvironment _Env;
public FileHelper(IHostingEnvironment Env)
{
_Env = Env;
}
但是,现实情况是,我们希望这个类里的方法都是静态方法,可以直接调用 FileHelper.MapPath(),当然这不是主要因素,主要因素是 我们在 其它的帮助类里也要调用这个方法,比如 我们在 Uitls 类里 有个读取文件内容的方法调用这个方法获取绝对路径,在两种情况下,构造器的注入显然是不合适的。
因此,我们如何去实现呢?
一:我们添加两个静态类 Extensions 、DI

二:在Startup.cs 的 Configure 方法中添加:

添加完这两个类,我们回到 FileHelper
定义两个静态字段:
DirectorySeparatorChar:目录分隔符,因为是跨平台的应用,我们要判断目录分隔符,windows 下是 "\", Mac OS and Linux 下是 "/"
_ContentRootPath:包含应用程序的目录的绝对路径

我们现在写一个获取文件绝对路径的静态方法 MapPath(string path)
逻辑是:①:判断是否是绝对路径,如果是绝对路径直接返回当前路径
②:如果不是绝对路径,我们通过 Path.Combine 组合路径,应用程序的目录的绝对路径 + 虚拟路径转绝对路径
/// <summary>
/// 获取文件绝对路径
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
public static string MapPath(string path)
{
return IsAbsolute(path) ? path : Path.Combine(_ContentRootPath , path.TrimStart('~','/').Replace("/", DirectorySeparatorChar));
}
说明:
_ContentRootPath 是我们在 开始 获取的 应用程序的绝对路径 private static string _ContentRootPath = DI.ServiceProvider.GetRequiredService<IHostingEnvironment>().ContentRootPath;
对于传递进来的 path , 我们首先用 TrimStart 去除路径中的“~”和 “/”,然后通过 Replace 替换 目录分隔符 为 当前系统的目录分隔符
IsAbsolute 是我们定义的方法,判断当前路径是否为绝对路径(见下文)
判断当前路径是否为绝对路径
我们用了一个简单的办法来判断当前路径是否为绝对路径,我们获取系统盘符,windows 的系统盘符为“:”;Mac OS 和 Linux 没有盘符的概念都是“/”开始,所以我们判断是否包含“\”:
/// <summary>
/// 是否是绝对路径
/// windows下判断 路径是否包含 ":"
/// Mac OS、Linux下判断 路径是否包含 "\"
/// </summary>
/// <param name="path">路径</param>
/// <returns></returns>
public static bool IsAbsolute(string path)
{
return Path.VolumeSeparatorChar == ':' ? path.IndexOf(Path.VolumeSeparatorChar) > : path.IndexOf('\\') > ;
}
文件的基本操作(这些操作基本跟以前没什么区别,给大家参考一下)
所有的路径,我们都用到了 IsAbsolute(path) ? path : MapPath(path),一个三元运算符,用户判断如果非绝对路径转为绝对路径。
检测指定路径是否存在:
/// <summary>
/// 检测指定路径是否存在
/// </summary>
/// <param name="path">路径</param>
/// <param name="isDirectory">是否是目录</param>
/// <returns></returns>
public static bool IsExist(string path,bool isDirectory)
{
return isDirectory ? Directory.Exists(IsAbsolute(path) ? path : MapPath(path)) : File.Exists(IsAbsolute(path) ? path : MapPath(path));
}
检测目录是否为空
/// <summary>
/// 检测目录是否为空
/// </summary>
/// <param name="path">路径</param>
/// <returns></returns>
public static bool IsEmptyDirectory(string path)
{
return Directory.GetFiles(IsAbsolute(path) ? path : MapPath(path)).Length <= && Directory.GetDirectories(IsAbsolute(path) ? path : MapPath(path)).Length <= ;
}
创建文件或目录
/// <summary>
/// 创建目录或文件
/// </summary>
/// <param name="path">路径</param>
/// <param name="isDirectory">是否是目录</param>
public static void CreateFiles(string path, bool isDirectory)
{
try {
if (!IsExist(path, isDirectory))
{
if (isDirectory)
Directory.CreateDirectory(IsAbsolute(path) ? path : MapPath(path));
else
{
FileInfo file = new FileInfo(IsAbsolute(path) ? path : MapPath(path));
FileStream fs = file.Create();
fs.Dispose();
}
}
}
catch(Exception ex)
{
throw ex;
}
}
删除文件或目录
/// <summary>
/// 删除目录或文件
/// </summary>
/// <param name="path">路径</param>
/// <param name="isDirectory">是否是目录</param>
public static void DeleteFiles(string path, bool isDirectory)
{
try
{
if (!IsExist(path, isDirectory))
{
if (isDirectory)
Directory.Delete(IsAbsolute(path) ? path : MapPath(path));
else
File.Delete(IsAbsolute(path) ? path : MapPath(path));
}
}
catch (Exception ex)
{
throw ex;
}
}
清空目录下所有文件及子目录,依然保留该目录
/// <summary>
/// 清空目录下所有文件及子目录,依然保留该目录
/// </summary>
/// <param name="path"></param>
public static void ClearDirectory(string path)
{
if(IsExist(path,true))
{
//目录下所有文件
string[] files = Directory.GetFiles(IsAbsolute(path) ? path : MapPath(path));
foreach(var file in files)
{
DeleteFiles(file, false);
}
//目录下所有子目录
string[] directorys = Directory.GetDirectories(IsAbsolute(path) ? path : MapPath(path));
foreach(var dir in directorys)
{
DeleteFiles(dir, true);
}
}
}
复制文件、移动文件
/// <summary>
/// 复制文件内容到目标文件夹
/// </summary>
/// <param name="sourcePath">源文件</param>
/// <param name="targetPath">目标文件夹</param>
/// <param name="isOverWrite">是否可以覆盖</param>
public static void Copy(string sourcePath,string targetPath,bool isOverWrite=true)
{
File.Copy(IsAbsolute(sourcePath) ? sourcePath : MapPath(sourcePath), (IsAbsolute(targetPath) ? targetPath : MapPath(targetPath))+ GetFileName(sourcePath), isOverWrite);
}
/// <summary>
/// 移动文件到目标目录
/// </summary>
/// <param name="sourcePath">源文件</param>
/// <param name="targetPath">目标目录</param>
public static void Move(string sourcePath, string targetPath)
{
string sourceFileName = GetFileName(sourcePath);
//如果目标目录不存在则创建
if(!IsExist(targetPath, true))
{
CreateFiles(targetPath, true);
}
else
{
//如果目标目录存在同名文件则删除
if (IsExist(Path.Combine(IsAbsolute(targetPath) ? targetPath : MapPath(targetPath), sourceFileName), false))
{
DeleteFiles(Path.Combine(IsAbsolute(targetPath) ? targetPath : MapPath(targetPath), sourceFileName), true);
}
} File.Move(IsAbsolute(sourcePath) ? sourcePath : MapPath(sourcePath), Path.Combine(IsAbsolute(targetPath) ? targetPath : MapPath(targetPath), sourceFileName)); }
获取文件名和扩展名
/// <summary>
/// 获取文件名和扩展名
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
public static string GetFileName(string path)
{
return Path.GetFileName(IsAbsolute(path) ? path : MapPath(path));
} /// <summary>
/// 获取文件名不带扩展名
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
public static string GetFileNameWithOutExtension(string path)
{
return Path.GetFileNameWithoutExtension(IsAbsolute(path) ? path : MapPath(path));
} /// <summary>
/// 获取文件扩展名
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
public static string GetFileExtension(string path)
{
return Path.GetExtension(IsAbsolute(path) ? path : MapPath(path));
}
修正:

对于是否是绝对路径,我们在MapPath(string path) 方法中已经做了判断,所以其它方法没有必要再次判断,其余方法中的 IsAbsolute(path) ? path : MapPath(path) 可直接改为 MapPath(path),
感谢@shoufengwei !
希望跟大家一起学习Asp.net Core
刚开始接触,水平有限,很多东西都是自己的理解和翻阅网上大神的资料,如果有不对的地方和不理解的地方,希望大家指正!
虽然Asp.net Core 现在很火热,但是网上的很多资料都是前篇一律的复制,所以有很多问题我也暂时没有解决,希望大家能共同帮助一下!
原创文章 转载请尊重劳动成果 http://yuangang.cnblogs.com
【无私分享:ASP.NET CORE 项目实战(第七章)】文件操作 FileHelper的更多相关文章
- 【无私分享:ASP.NET CORE 项目实战(第九章)】创建区域Areas,添加TagHelper
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在Asp.net Core VS2015中,我们发现还有很多不太简便的地方,比如右击添加视图,转到试图页等功能图不见了,虽然我 ...
- 【无私分享:ASP.NET CORE 项目实战(第二章)】添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 上一章,我们介绍了安装和新建控制器.视图,这一章我们来创建个数据模型,并且添加接口和实现类. 添加EF上下文对象 按照我们以前 ...
- [转]【无私分享:ASP.NET CORE 项目实战(第九章)】创建区域Areas,添加TagHelper
本文转自:http://www.cnblogs.com/zhangxiaolei521/p/5808417.html 目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在Asp ...
- 【无私分享:ASP.NET CORE 项目实战】目录索引
简介 首先,我们的 [无私分享:从入门到精通ASP.NET MVC] 系列已经接近尾声,希望大家在这个过程中学到了一些思路和方法,而不仅仅是源码. 因为是第一次写博客,我感觉还是比较混乱的,其中 ...
- 【无私分享:ASP.NET CORE 项目实战(第十四章)】图形验证码的实现
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 很长时间没有来更新博客了,一是,最近有些忙,二是,Core也是一直在摸索中,其实已经完成了一个框架了,并且正在准备在生产环境中 ...
- 【无私分享:ASP.NET CORE 项目实战(第十三章)】Asp.net Core 使用MyCat分布式数据库,实现读写分离
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 MyCat2.0版本很快就发布了,关于MyCat的动态和一些问题,大家可以加一下MyCat的官方QQ群:106088787.我 ...
- 【无私分享:ASP.NET CORE 项目实战(第十二章)】添加对SqlServer、MySql、Oracle的支持
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 增加对多数据库的支持,并不是意味着同时对多种数据库操作,当然,后面,我们会尝试同时对多种数据库操作,这可能需要多个上下文,暂且 ...
- 【无私分享:ASP.NET CORE 项目实战(第十一章)】Asp.net Core 缓存 MemoryCache 和 Redis
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 经过 N 久反复的尝试,翻阅了网上无数的资料,GitHub上下载了十几个源码参考, Memory 和 Redis 终于写出一个 ...
- 【无私分享:ASP.NET CORE 项目实战(第十章)】发布项目到 Linux 上运行 Core 项目
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 ASP.Net Core 给我们带来的最大的亮点就是跨平台,我在我电脑(win7)上用虚拟机建了个 CentOS7 ,来演示下 ...
- 【无私分享:ASP.NET CORE 项目实战(第八章)】读取配置文件(二) 读取自定义配置文件
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 我们在 读取配置文件(一) appsettings.json 中介绍了,如何读取appsettings.json. 但随之产生 ...
随机推荐
- AFNetworking 3.0 源码解读 总结(干货)(上)
养成记笔记的习惯,对于一个软件工程师来说,我觉得很重要.记得在知乎上看到过一个问题,说是人类最大的缺点是什么?我个人觉得记忆算是一个缺点.它就像时间一样,会自己消散. 前言 终于写完了 AFNetwo ...
- AFNetworking 3.0 源码解读(十)之 UIActivityIndicatorView/UIRefreshControl/UIImageView + AFNetworking
我们应该看到过很多类似这样的例子:某个控件拥有加载网络图片的能力.但这究竟是怎么做到的呢?看完这篇文章就明白了. 前言 这篇我们会介绍 AFNetworking 中的3个UIKit中的分类.UIAct ...
- Oracle 数据库知识汇总篇
Oracle 数据库知识汇总篇(更新中..) 1.安装部署篇 2.管理维护篇 3.数据迁移篇 4.故障处理篇 5.性能调优篇 6.SQL PL/SQL篇 7.考试认证篇 8.原理体系篇 9.架构设计篇 ...
- AI人工智能系列随笔:syntaxnet 初探(1)
人工智能是 最近的一个比较火的名词,相信大家对于阿尔法狗都不陌生吧?其实我对人工智能以前也是非常抵触的,因为我认为机器人会取代人类,成为地球乃至宇宙的霸主,但是人工智能带给我的这种冲击,我个人感觉是欲 ...
- 【走过巨坑】android studio对于jni调用及运行闪退无法加载库的问题解决方案
相信很多小伙伴都在android开发中遇到调用jni的各种巨坑,因为我们不得不在很多地方用到第三方库so文件,然而第三方官方通常都只会给出ADT环境下的集成方式,而谷歌亲儿子android studi ...
- [原] KVM 虚拟化原理探究(6)— 块设备IO虚拟化
KVM 虚拟化原理探究(6)- 块设备IO虚拟化 标签(空格分隔): KVM [toc] 块设备IO虚拟化简介 上一篇文章讲到了网络IO虚拟化,作为另外一个重要的虚拟化资源,块设备IO的虚拟化也是同样 ...
- java中易错点(二)
java,exe是java虚拟机 javadoc.exe用来制作java文档 jdb.exe是java的调试器 javaprof,exe是剖析工具 解析一: sleep是线程类(Thread)的方法, ...
- SQLServer2005创建定时作业任务
SQLServer定时作业任务:即数据库自动按照定时执行的作业任务,具有周期性不需要人工干预的特点 创建步骤:(使用最高权限的账户登录--sa) 一.启动SQL Server代理(SQL Server ...
- vim安装中文帮助手册
安装方法: 在下面的网站下载中文帮助的文件包:$wget http://nchc.dl.sourceforge.net/sourceforge/vimcdoc/vimcdoc-1.5.0.tar. ...
- Ubuntu下利用Mono,Jexus搭建Asp.Net(MVC) Web服务器
最近在Ubuntu上搭建了Asp.Net的Web服务器,其中遇到很多问题,整理一下思路,以备后用. 搭建环境以及配套软件 Ubuntu: 11.10 Mono:3.0.6 下载地址(http://do ...