0

0

分享一个磁盘文件查看系统

零下一度

零下一度

发布时间:2017-06-24 10:14:06

|

1677人浏览过

|

来源于php中文网

原创

本篇和大家分享的是一个磁盘文件查看系统,严格来说是使用NetCore写的一个Web系统应用,由于NetCore跨平台特性,我生成了exe的运行包,只需要配置运行电脑ip+端口,即可在浏览器中通过IP+端口的方式访问目标调用上的所有目录,不错是所有目录(如果您有:C,D,E,F盘都可以访问),当然为了安全最好限制下;还有上传,备份功能,具体看下面的分享内容吧;git地址:

查看器功能说明与演示

本查看器主要是为了方便大家查看服务器上的日志,这里没有考虑其他安全性问题,比如特定人员登录才能查看,这个需要您们自己去增加;如果你服务器有对外开放了ip,那么运行这个软件的时候建议考虑配置成您们公司内网的ip,这里可以避免一些安全性问题;下面是主要功能:

. 通过可以定义文件配置常用磁盘访问地址

. 查看磁盘目录下的文件夹和文件

. 部分可访问行文件(如:txt,DLL,图片等)可以在浏览器中打开或下载(访问性格式由程序配置)

. 上传多个文件到指定磁盘

. 文件备份(如果上传的文件已经存在,会自动备份到bak文件夹中)

效果gif图片,有点花多多包涵:

效果还可以吧,不妨“推荐”下;

 

磁盘列表功能

首先,要明确的是在NetCore1.1中api已经和大部分能和framwork对应上了(据@善友一篇博客简单介绍说NetCore2.0的api已经能够和framwork持平了),因此这里我们能够直接使用DirectoryInfo,来查看磁盘路径的文件夹和文件,所以就有了查看列表Action的代码:

 1  ///  2         /// 磁盘列表 3         ///  4         /// 磁盘路径 5         ///  6         public IActionResult Index(string path) 7         { 8             Console.WriteLine($"IP:{HttpContext.Connection.RemoteIpAddress}正在查看磁盘:{path}"); 9             var list = new List();10             MoSearch moSerach = new MoSearch { Txt1 = path };11             ViewData["Search"] = moSerach;12 13             if (string.IsNullOrWhiteSpace(path)) { return View(list); }14             if (path.StartsWith("c:", StringComparison.OrdinalIgnoreCase)) { this.MsgBox($"无权限访问:{path}"); return View(list); }15             if (!System.IO.Directory.Exists(path)) { this.MsgBox($"磁盘路径:{path}不存在!"); return View(list); }16             DirectoryInfo dic = new DirectoryInfo(path);17             list = dic.GetFileSystemInfos().OrderByDescending(b => b.LastWriteTime).ToList();18 19             return View(list);20         }

这里我默认限制了C盘,并且采用自带的文件对象FileSystemInfo来返回信息,仅仅只需要一段 dic.GetFileSystemInfos().OrderByDescending(b => b.LastWriteTime).ToList() 就能获取按照最新修改时间得到磁盘目录信息;对应的View布局如下:

  1 @using System.IO  2 @using ShenNiu.LogTool.Extension;  3 @using ShenNiu.LogTool.Controllers  4 @model List  5 @{  6     ViewData["Title"] = "日志搜索";  7   8     var moSearch = ViewData["Search"] as MoSearch;  9 } 10 
11

@ViewData["Title"]

12
13
14
15 16 17
18
19 20 29 30
31
32 33
34 35 36 返 回 37 38 @ViewData["msg"] 39 40
41
42 43 44 45 46 47 48 49 50 51 52 53 @foreach (var item in Model) 54 { 55 56 71 72 73 74 80 81 } 82 83
文件名磁盘路径最后更新时间创建时间操作
57 @if (item.Attributes == FileAttributes.Archive) 58 { 59 分享一个磁盘文件查看系统@item.Name 60 } 61 else if (item.Attributes == FileAttributes.Directory) 62 { 63 分享一个磁盘文件查看系统@item.Name 64 } 65 else 66 { 67 分享一个磁盘文件查看系统@item.Name 68 } 69 @item.Attributes 70 @item.FullName@item.LastWriteTime@item.CreationTime 75 @if (item.Attributes == FileAttributes.Archive) 76 { 77 查看 78 } 79
84
@ViewData["msg"]
85
86

列表页面的常用地址来源有系统配置文件配置的,通过前端ajax调用接口获取配置的json内容,接口Action代码:

 1  public async Task GetSelData() 2         { 3             var apiUrl = $"http://{Request.Host.Host}:{Request.Host.Port}/js/tooldata/logconf.json"; 4             var str = string.Empty; 5             using (HttpClient client = new HttpClient()) 6             { 7                 client.BaseAddress = new Uri(apiUrl); 8                 str = await client.GetStringAsync(apiUrl); 9             }10             return Content(str);11         }

配置文件格式和内容如:

 1 [ 2   { 3     "gname": "日志", 4     "gval": [ 5       { 6         "name": "JokeLog", 7         "val": "D:\\D\\Joke" 8       } 9     ]10   },11   {12     "gname": "D盘",13     "gval": [14       {15         "name": "D盘",16         "val": "D:\\"17       }18     ]19   }20 ]

 

指定磁盘目录上传文件和自动备份

通常咋们有这样的情况,我们没有直接访问服务器的权限,想上传个东西很麻烦,每次只能通过运维(当然这是正规的流程),可是往往一些特殊情况不得不自己传递个东西发布,因此这里增加了上传功能,并且上传时候如果已存在相同文件,那么在覆盖之前会自动增加备份到tempbak中去;

 1 ///  2         /// 本查看系统具有上传文件的功能 3         ///  4         ///  5         [HttpPost] 6         public async Task AjaxFileUp() 7         { 8             var data = new MoData { Msg = "上传失败" }; 9             try10             {11                 var upPath = Request.Form["txt1"];12                 if (string.IsNullOrWhiteSpace(upPath)) { data.Msg = "请在【磁盘路径】输入框输入上传路径。"; return Json(data); }13                 if (!System.IO.Directory.Exists(upPath)) { data.Msg = $"磁盘路径:{upPath}不存在!"; return Json(data); }14                 upPath = upPath.ToString().TrimEnd('\\');15 16                 var files = Request.Form.Files.Where(b => b.Name == "upFile");17                 //非空限制18                 if (files == null || files.Count() <= 0) { data.Msg = "请选择上传的文件。"; return Json(data); }19 20                 //格式限制21                 //var allowType = new string[] { "image/jpeg", "image/png" };22                 //if (files.Any(b => !allowType.Contains(b.ContentType)))23                 //{24                 //    data.Msg = $"只能上传{string.Join(",", allowType)}格式的文件。";25                 //    return Json(data);26                 //}27 28                 //大小限制29                 var nMax = 20;30                 if (files.Sum(b => b.Length) >= 1024 * 1024 * nMax)31                 {32                     data.Msg = $"上传文件的总大小只能在{nMax}M以下。"; return Json(data);33                 }34 35                 //删除过去备份的文件36                 var basePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "tempbak");37                 DirectoryInfo dic = new DirectoryInfo(basePath);38                 var nCount = dic.GetFiles().Count();39                 var nMaxCount = 10;40                 if (nCount > nMaxCount)  //大于nMaxCount个文件清空临时目录41                 {42                     foreach (var item in dic.GetFiles().OrderBy(b => b.LastWriteTime).Take(nCount - nMaxCount))43                     {44                         try45                         {46                             item.Delete();47                         }48                         catch (Exception ex) { }49                     }50                 }51 52                 //写入服务器磁盘53                 var upLog = new StringBuilder(string.Empty);54                 foreach (var file in files)55                 {56 57                     var fileName = file.FileName;58                     var path = Path.Combine(upPath, fileName);59                     upLog.AppendFormat("文件:{0};", path);60 61                     //存在文件需要备份62                     if (System.IO.File.Exists(path))63                     {64                         FileInfo info = new FileInfo(path);65                         var tempPath = Path.Combine(basePath, info.Name); //备份目录66                         var newInfo = info.CopyTo(tempPath, true);67                         if (newInfo == null) { upLog.Append($"备份:失败,请稍后重试!"); }68                         else { upLog.Append($"备份:成功!"); }69                     }70 71                     using (var stream = System.IO.File.Create(path))72                     {73                         await file.CopyToAsync(stream);74                     }75                     upLog.Append($"上传:成功;
");76 }77 data.Msg = upLog.ToString();78 data.Status = 2;79 }80 catch (Exception ex)81 {82 data.Msg += ex.Message;83 }84 Console.WriteLine($"IP:{HttpContext.Connection.RemoteIpAddress}正在上传:{data.Msg}");85 return Json(data);86 }

关键点的逻辑代码已经有注释了这里就不多说了,主要满足咋们的业务:上传+备份;至于上传的js代码已经在上面的列表试图中了这里就不重复贴出来了;这里用到了几个自定义实体类:

 1 ///  2     /// 接口统一类 3     ///  4     public class MoData 5     { 6         public string Msg { get; set; } 7  8         public int Status { get; set; } 9     }10 11     /// 12     /// 搜索类13     /// 14     public class MoSearch15     {16         public string Txt1 { get; set; }17 18         public string Sel1 { get; set; }19     }20 21     /// 22     /// 文件23     /// 24     public class MoFile25     {26         public string Name { get; set; }27         public string Path { get; set; }28         public string Url { get; set; }29         public string Content { get; set; }30         public FileAttributes Attributes { get; set; }31     }

 

直接查看内容

该系统可以直接查看如:txt,log等后缀的文件,因为这种类型的文件一般都有读,写同时操作的情况,所以这里我采用的方式是先拷贝当前访问的文件到temp临时目录中,然后在读取内容或下载文件;当满足超过10个文件的设置,那么自动删除修改时间最小的文件,避免拷贝文件一直增多导致磁盘空间的成本;下面是读取Action的内容:

 1 ///  2         /// 查看内容 
 3         ///  4         ///  5         ///  6         public async Task Read(string path) 7         { 8             Console.WriteLine($"IP:{HttpContext.Connection.RemoteIpAddress}正在查看文件:{path}"); 9 10             var moFile = new MoFile { Path = path };11             if (string.IsNullOrWhiteSpace(path)) { this.MsgBox($"文件路径:{path}不存在。"); return View(moFile); }12             if (!System.IO.File.Exists(path)) { this.MsgBox($"文件路径:{path}不存在!"); return View(moFile); }13 14             try15             {16                 FileInfo info = new FileInfo(path);17                 //if (!ExtensionClass._AllowExtension.Any(b => b.ToUpper() == info.Extension.ToUpper()))18                 //{19                 //    this.MsgBox($"无法访问{info.Extension}的文件"); return View(moFile);20                 // }21 22                 var basePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "temp");23                 DirectoryInfo dic = new DirectoryInfo(basePath);24                 var nCount = dic.GetFiles().Count();25                 var nMaxCount = 10;26                 if (nCount > nMaxCount)  //大于nMaxCount个文件清空临时目录27                 {28                     foreach (var item in dic.GetFiles().OrderBy(b => b.LastWriteTime).Take(nCount - nMaxCount))29                     {30                         try31                         {32                             item.Delete();33                         }34                         catch (Exception ex) { }35                     }36                 }37 38                 var tempPath = Path.Combine(basePath, info.Name);39                 var newInfo = info.CopyTo(tempPath, true);40                 if (newInfo == null) { this.MsgBox($"文件:{path}查看失败,请稍后重试!"); return View(moFile); }41 42                 moFile.Name = newInfo.Name;43                 moFile.Url = $"/{moFile.Name}";44                 moFile.Attributes = newInfo.Attributes;45                 if (moFile.Attributes == FileAttributes.Archive && !ExtensionClass._FileExtension.Any(b => b == newInfo.Extension))46                 {47                     using (var stream = newInfo.OpenRead())48                     {49                         using (var reader = new StreamReader(stream))50                         {51                             moFile.Content = await reader.ReadToEndAsync();52                         }53                     }54                 }55             }56             catch (Exception ex)57             {58                 this.MsgBox($"文件:{path}查看失败,请稍后重试!");59             }60             return View(moFile);61         }

 

怎么使用ShenNiu.LogTool工具呢

我这里只提供了一个windows x64平台的运行exe包ShenNiu.LogTool(不用安装什么运行环境),只需要双击“ShenNiu.LogTool.exe”-》配置Ip+端口(默认IP:127.0.0.1,端口:12345):

-》浏览器中输入:http://127.0.0.1:12345/Log 即可访问查看系统,剩下的操作就如上gif截图了;

 

使用nssm工具把NetCore生成的exe转成windows服务

本篇到这里还要讲一个工具nssm(这里不提供下载地址,个位网搜吧),因为就windows平台而言netcore生成如果不用iis发布,那么大多数都是通过exe来运行的,但是我们不可能再服务器上开很多个黑屏cmd一样的窗体,那这样服务器每次关闭的话那就用不了服务了;因此我们使用nssm把这个netcore上传的exe转成windows服务中去,这样就算关机重启也能及时启动;

由于windows服务不会提示让咋们输入绑定的ip,端口,所以这里我们需要改改代码:

 1 public static void Main(string[] args) 2         { 3             Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 4             Console.OutputEncoding = Encoding.GetEncoding("GB2312"); 5  6             //Console.WriteLine("输入服务绑定的Ip:"); 7             //var strHost = Console.ReadLine(); if (string.IsNullOrWhiteSpace(strHost)) { strHost = "127.0.0.1"; } 8             //Console.WriteLine("输入服务绑定的端口:"); 9             //var strPort = Console.ReadLine(); if (string.IsNullOrWhiteSpace(strPort)) { strPort = "12345"; }10 11             //var hostAndPort = $"http://{strHost}:{strPort}";12             var hostAndPort = "http://127.0.0.1:12345";13 14             var host = new WebHostBuilder()15                 .UseKestrel()16                 .UseUrls(hostAndPort)17                 .UseContentRoot(Directory.GetCurrentDirectory())18                 .UseIISIntegration()19                 .UseStartup()20                 .UseApplicationInsights()21                 .Build();22 23             host.Run();24         }

然后利用nssm工具,首先通过cmd命令执行如下命令:

执行后会弹出一个框,然后如图操作:

再点击“install server”,不出意外的话会弹出一个 successful的提示;再来咋们看看windows服务中我们注册的服务:

这个时候该服务是未启动状态,所以我们可以直接通过操作界面启动下(当然也可以通过nssm命令启动),能正常启动没问题的话,我们就可以在浏览器中访问:http://127.0.0.1:12345/Log:

好了本章到此就结束了,怎么样干货还是可以吧,不妨点个"推荐",谢谢。再发下git地址:

 

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
全国统一发票查询平台入口合集
全国统一发票查询平台入口合集

本专题整合了全国统一发票查询入口地址合集,阅读专题下面的文章了解更多详细入口。

19

2026.02.03

短剧入口地址汇总
短剧入口地址汇总

本专题整合了短剧app推荐平台,阅读专题下面的文章了解更多详细入口。

27

2026.02.03

植物大战僵尸版本入口地址汇总
植物大战僵尸版本入口地址汇总

本专题整合了植物大战僵尸版本入口地址汇总,前往文章中寻找想要的答案。

15

2026.02.03

c语言中/相关合集
c语言中/相关合集

本专题整合了c语言中/的用法、含义解释。阅读专题下面的文章了解更多详细内容。

3

2026.02.03

漫蛙漫画网页版入口与正版在线阅读 漫蛙MANWA官网访问专题
漫蛙漫画网页版入口与正版在线阅读 漫蛙MANWA官网访问专题

本专题围绕漫蛙漫画(Manwa / Manwa2)官网网页版入口进行整理,涵盖漫蛙漫画官方主页访问方式、网页版在线阅读入口、台版正版漫画浏览说明及基础使用指引,帮助用户快速进入漫蛙漫画官网,稳定在线阅读正版漫画内容,避免误入非官方页面。

13

2026.02.03

Yandex官网入口与俄罗斯搜索引擎访问指南 Yandex中文登录与网页版入口
Yandex官网入口与俄罗斯搜索引擎访问指南 Yandex中文登录与网页版入口

本专题汇总了俄罗斯知名搜索引擎 Yandex 的官网入口、免登录访问地址、中文登录方法与网页版使用指南,帮助用户稳定访问 Yandex 官网,并提供一站式入口汇总。无论是登录入口还是在线搜索,用户都能快速获取最新稳定的访问链接与使用指南。

114

2026.02.03

Java 设计模式与重构实践
Java 设计模式与重构实践

本专题专注讲解 Java 中常用的设计模式,包括单例模式、工厂模式、观察者模式、策略模式等,并结合代码重构实践,帮助学习者掌握 如何运用设计模式优化代码结构,提高代码的可读性、可维护性和扩展性。通过具体示例,展示设计模式如何解决实际开发中的复杂问题。

3

2026.02.03

C# 并发与异步编程
C# 并发与异步编程

本专题系统讲解 C# 异步编程与并发控制,重点介绍 async 和 await 关键字、Task 类、线程池管理、并发数据结构、死锁与线程安全问题。通过多个实战项目,帮助学习者掌握 如何在 C# 中编写高效的异步代码,提升应用的并发性能与响应速度。

2

2026.02.03

Python 强化学习与深度Q网络(DQN)
Python 强化学习与深度Q网络(DQN)

本专题深入讲解 Python 在强化学习(Reinforcement Learning)中的应用,重点介绍 深度Q网络(DQN) 及其实现方法,涵盖 Q-learning 算法、深度学习与神经网络的结合、环境模拟与奖励机制设计、探索与利用的平衡等。通过构建一个简单的游戏AI,帮助学习者掌握 如何使用 Python 训练智能体在动态环境中作出决策。

3

2026.02.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
ASP.NET参考手册
ASP.NET参考手册

共0课时 | 0人学习

传播智客ASP.NET中级系列视频教程
传播智客ASP.NET中级系列视频教程

共33课时 | 6.4万人学习

传播智客ASP.NET高级系列视频教程
传播智客ASP.NET高级系列视频教程

共34课时 | 6.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号