搜尋
首頁後端開發C#.Net教程分享一個磁碟檔案檢視系統

分享一個磁碟檔案檢視系統

Jun 24, 2017 am 10:14 AM
asp.netcoreweb共享文件磁碟

本篇和大家分享的是一个磁盘文件查看系统,严格来说是使用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  /// <summary> 2         /// 磁盘列表 3         /// </summary> 4         /// <param>磁盘路径 5         /// <returns></returns> 6         public IActionResult Index(string path) 7         { 8             Console.WriteLine($"IP:{HttpContext.Connection.RemoteIpAddress}正在查看磁盘:{path}"); 9             var list = new List<filesysteminfo>();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         }</filesysteminfo>

这里我默认限制了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<filesysteminfo>  5 @{  6     ViewData["Title"] = "日志搜索";  7   8     var moSearch = ViewData["Search"] as MoSearch;  9 } 10 <div> 11     <h4 id="ViewData-Title">@ViewData["Title"]</h4> 12     <hr> 13     <form> 14         <div> 15             <label>磁盘路径</label> 16             <input> 17         </div> 18         <div> 19             <label>常用地址</label> 20             <select> 21                 @*<option>==请选择==</option> 22                     <optgroup> 23                         <option>D:\D\Joke</option> 24                     </optgroup> 25                     <optgroup> 26                         <option>D盘</option> 27                     </optgroup>*@ 28             </select> 29  30         </div> 31         <div> 32             <input> 33         </div> 34         <button>查 询</button> 35         <button>上 传</button> 36         <a>返 回</a> 37         <span> 38             @ViewData["msg"] 39         </span> 40     </form> 41     <hr> 42     <table> 43         <thead> 44             <tr> 45                 <th>文件名</th> 46                 <th>磁盘路径</th> 47                 <th>最后更新时间</th> 48                 <th>创建时间</th> 49                 <th>操作</th> 50             </tr> 51         </thead> 52         <tbody> 53             @foreach (var item in Model) 54             { 55             <tr> 56                 <td> 57                     @if (item.Attributes == FileAttributes.Archive) 58                         { 59                         <img  src="/static/imghwm/default1.png" data-src="/images/icon/@(item.Extension.GetExtensionIcon())" class="lazy" alt="分享一個磁碟檔案檢視系統" ><a>@item.Name</a> 60                         } 61                         else if (item.Attributes == FileAttributes.Directory) 62                         { 63                         <img  src="/static/imghwm/default1.png" data-src="/images/icon/Directory1.jpg" class="lazy" alt="分享一個磁碟檔案檢視系統" ><a>@item.Name</a> 64                         } 65                         else 66                         { 67                         <img  src="/static/imghwm/default1.png" data-src="/images/icon/@(item.Extension.GetExtensionIcon())" class="lazy" alt="分享一個磁碟檔案檢視系統" ><a>@item.Name</a> 68                         } 69                     @item.Attributes 70                 </td> 71                 <td>@item.FullName</td> 72                 <td>@item.LastWriteTime</td> 73                 <td>@item.CreationTime</td> 74                 <td> 75                     @if (item.Attributes == FileAttributes.Archive) 76                         { 77                         <a>查看</a> 78                         } 79                 </td> 80             </tr> 81             } 82         </tbody> 83     </table> 84     <div>@ViewData["msg"]</div> 85 </div> 86 <script> 87     $(function(){ 88  89     $("#btnUp").on("click", function () { 90             var msg = $("#span01"); 91             var form = document.getElementById("form01"); 92             //console.log(form); 93             var data = new FormData(form); 94  95             $.ajax({ 96                 type: "POST", 97                 url: "/log/AjaxFileUp", 98                 data: data, 99 100                 contentType: false,101                 processData: false,102                 success: function (data) {103                     if (data) {104                         msg.html(data.msg);105                     }106                 },107                 error: function () {108                     msg.html("上传文件异常,请稍后重试!");109                 }110             });111         });112 113         $("#btnSearch").on("click",function(){114 115          var sel1Val = $.trim($("select[name=&#39;sel1&#39;] option:selected").val());116          var txt1Val = $.trim($("#txt1").val());117 118 119          var pathVal = sel1Val.length<=0?txt1Val:sel1Val;120          window.location.href="/log/index?path="+pathVal;121         });122 123         $.getJSON("/log/GetSelData",function(data){124             console.log(data);125             if(data){126 127 128 129                 var sel1 = $("select[name=&#39;sel1&#39;]");130                 var gArr = [];131                 gArr.push(&#39;<option value="">==请选择==&#39;);132                 $.each(data,function(i,item){133 134                     gArr.push(&#39;<optgroup label="&#39;+item.gname+&#39;">&#39;);135 136                     $.each(item.gval,function(i2,item2){137 138                          gArr.push(&#39;<option value="&#39;+item2.val+&#39;">&#39;+item2.name+&#39;&#39;);139                     });140 141                     gArr.push(&#39;&#39;);142                 });143 144                 sel1.html(gArr.join(&#39;&#39;));145             }146         });147     })148 </script></filesysteminfo>

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

 1  public async Task<contentresult> 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         }</contentresult>

配置文件格式和内容如:

 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 /// <summary> 2         /// 本查看系统具有上传文件的功能 3         /// </summary> 4         /// <returns></returns> 5         [HttpPost] 6         public async Task<jsonresult> 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()  !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($"上传:成功;<br>");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         }</jsonresult>

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

 1 /// <summary> 2     /// 接口统一类 3     /// </summary> 4     public class MoData 5     { 6         public string Msg { get; set; } 7  8         public int Status { get; set; } 9     }10 11     /// <summary>12     /// 搜索类13     /// </summary>14     public class MoSearch15     {16         public string Txt1 { get; set; }17 18         public string Sel1 { get; set; }19     }20 21     /// <summary>22     /// 文件23     /// </summary>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 /// <summary> 2         /// 查看内容 
 3         /// </summary> 4         /// <param> 5         /// <returns></returns> 6         public async Task<iactionresult> 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         }</iactionresult>

 

怎么使用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<startup>()20                 .UseApplicationInsights()21                 .Build();22 23             host.Run();24         }</startup>

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

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

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

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

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

 

以上是分享一個磁碟檔案檢視系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
從網絡到桌面:C#.NET的多功能性從網絡到桌面:C#.NET的多功能性Apr 15, 2025 am 12:07 AM

C#.NETisversatileforbothwebanddesktopdevelopment.1)Forweb,useASP.NETfordynamicapplications.2)Fordesktop,employWindowsFormsorWPFforrichinterfaces.3)UseXamarinforcross-platformdevelopment,enablingcodesharingacrossWindows,macOS,Linux,andmobiledevices.

C#.NET與未來:適應新技術C#.NET與未來:適應新技術Apr 14, 2025 am 12:06 AM

C#和.NET通過不斷的更新和優化,適應了新興技術的需求。 1)C#9.0和.NET5引入了記錄類型和性能優化。 2).NETCore增強了雲原生和容器化支持。 3)ASP.NETCore與現代Web技術集成。 4)ML.NET支持機器學習和人工智能。 5)異步編程和最佳實踐提升了性能。

c#.net適合您嗎?評估其適用性c#.net適合您嗎?評估其適用性Apr 13, 2025 am 12:03 AM

c#.netissutableforenterprise-levelapplications withemofrosoftecosystemdueToItsStrongTyping,richlibraries,androbustperraries,androbustperformance.however,itmaynotbeidealfoross-platement forment forment forment forvepentment offependment dovelopment toveloperment toveloperment whenrawspeedsportor whenrawspeedseedpolitical politionalitable,

.NET中的C#代碼:探索編程過程.NET中的C#代碼:探索編程過程Apr 12, 2025 am 12:02 AM

C#在.NET中的編程過程包括以下步驟:1)編寫C#代碼,2)編譯為中間語言(IL),3)由.NET運行時(CLR)執行。 C#在.NET中的優勢在於其現代化語法、強大的類型系統和與.NET框架的緊密集成,適用於從桌面應用到Web服務的各種開發場景。

C#.NET:探索核心概念和編程基礎知識C#.NET:探索核心概念和編程基礎知識Apr 10, 2025 am 09:32 AM

C#是一種現代、面向對象的編程語言,由微軟開發並作為.NET框架的一部分。 1.C#支持面向對象編程(OOP),包括封裝、繼承和多態。 2.C#中的異步編程通過async和await關鍵字實現,提高應用的響應性。 3.使用LINQ可以簡潔地處理數據集合。 4.常見錯誤包括空引用異常和索引超出範圍異常,調試技巧包括使用調試器和異常處理。 5.性能優化包括使用StringBuilder和避免不必要的裝箱和拆箱。

測試C#.NET應用程序:單元,集成和端到端測試測試C#.NET應用程序:單元,集成和端到端測試Apr 09, 2025 am 12:04 AM

C#.NET應用的測試策略包括單元測試、集成測試和端到端測試。 1.單元測試確保代碼的最小單元獨立工作,使用MSTest、NUnit或xUnit框架。 2.集成測試驗證多個單元組合的功能,常用模擬數據和外部服務。 3.端到端測試模擬用戶完整操作流程,通常使用Selenium進行自動化測試。

高級C#.NET教程:ACE您的下一次高級開發人員面試高級C#.NET教程:ACE您的下一次高級開發人員面試Apr 08, 2025 am 12:06 AM

C#高級開發者面試需要掌握異步編程、LINQ、.NET框架內部工作原理等核心知識。 1.異步編程通過async和await簡化操作,提升應用響應性。 2.LINQ以SQL風格操作數據,需注意性能。 3..NET框架的CLR管理內存,垃圾回收需謹慎使用。

C#.NET面試問題和答案:提高您的專業知識C#.NET面試問題和答案:提高您的專業知識Apr 07, 2025 am 12:01 AM

C#.NET面試問題和答案包括基礎知識、核心概念和高級用法。 1)基礎知識:C#是微軟開發的面向對象語言,主要用於.NET框架。 2)核心概念:委託和事件允許動態綁定方法,LINQ提供強大查詢功能。 3)高級用法:異步編程提高響應性,表達式樹用於動態代碼構建。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中