C# 远程下载服务器文件到本机

4 篇文章 0 订阅
本文介绍了一个ASP.NET应用程序中如何实现日志文件的下载功能。通过在页面加载时填充下拉框显示日志文件名,然后使用AJAX调用后台服务,将文件流转为JSON并触发页面下载。在处理文件流时,特别注意了防止中文乱码问题,通过指定正确的编码格式解决了这一问题。此外,还讨论了下载远程服务器文件的场景,提到了WebClient的使用。
摘要由CSDN通过智能技术生成

好久没有更新文章了,最近一直在出差。这次甲方希望系统可以下载日志文件以查看设备的启停运行情况,我就在页面中添加了一个按钮和一个下拉框来实现下载文件(毕竟新需求没给钱,怎么简单怎么做吧)

首先需要将日志文件(日志使用NLog进行记录,存放在了项目下的logs文件夹下)查询出来放入下拉框中,下拉框我使用的是 aspx控件dropdownlist,在页面加载时进行一次文件名查询和下拉框元素初始化,部分代码如下:

xxPage.aspx:

<asp:DropDownList id="fileName" runat="server" style="height:25px;width:140px;" >

</asp:DropDownList>

xxPage.aspx.cs:

    protected void Page_Load(object sender, EventArgs e)
        {
            //查询所有日志文件名称
            var FilePath = System.Web.Hosting.HostingEnvironment.MapPath(@"~/logs/");
            List<string> fileNames = getAllFiles(FilePath);

            this.fileName.DataSource = fileNames;
            this.fileName.DataBind();
        }

        /// <summary>
        /// 获取所有文件
        /// </summary>
        /// <returns></returns>
        private List<string> getAllFiles(string dir)
        {
            List<string> FilesList = new List<string>();
            DirectoryInfo fileDire = new DirectoryInfo(dir);
            if (!fileDire.Exists)
            {
                throw new System.IO.FileNotFoundException("目录:" + fileDire.FullName + "没有找到!");
            }
            this.getAllDirFiles(fileDire, FilesList);
            this.getAllDirsFiles(fileDire.GetDirectories(), FilesList);
            return FilesList;
        }

        /// <summary>
        /// 获取一个文件夹下的所有文件夹里的文件
        /// </summary>
        /// <param name="dirs"></param>
        /// <param name="filesList"></param>
        private void getAllDirsFiles(DirectoryInfo[] dirs, List<string> filesList)
        {
            foreach (DirectoryInfo dir in dirs)
            {
                foreach (FileInfo file in dir.GetFiles("*.*"))
                {
                    filesList.Add(file.Name);
                }
                this.getAllDirsFiles(dir.GetDirectories(), filesList);
            }
        }

        /// <summary>
        /// 获取一个文件夹下的文件
        /// </summary>
        /// <param name="strDirName">目录名称</param>
        /// <param name="filesList">文件列表HastTable</param>
        private void getAllDirFiles(DirectoryInfo dir, List<string> filesList)
        {
            foreach (FileInfo file in dir.GetFiles("*.*"))
            {
                //filesList.Add(file.LastWriteTime);
                filesList.Add(file.Name);
            }
        }

接下来开始做下载部分,这里直接使用ajax来调用后台服务,获取指定文件的文件流,转为json数据传回给ajax,然后进行页面下载。部分代码如下:

xxPage.aspx:

<div id="controlLog"style="float:left; margin-top:10px;">
     <a href="#" id="controlLog1" class="easyui-linkbutton" onclick="javascript:return onLogDownload()" style="height:35px;width:140px;text-align:center;line-height:35px">日志下载</a>
</div>

在这里没有使用form的submit提交,而是使用这个linkbutton纯粹是因为要与页面中其他按钮格式保持一致,使用什么方式提交其实都行。

xxPage.js:

function onLogDownload() {     //2021-06-04
        var fileName= $('select#fileName').find('option:selected').val();
        var url = '../../WebPage/xxPage.ashx?method=logFileDownload&&logDate=' + fileName;
        var xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);        // 也可以使用POST方式,根据接口
        xhr.setRequestHeader("Content-Type", "application/json;charset=utf-8");
        xhr.responseType = "blob";    // 返回类型blob
        // 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
        xhr.onload = function () {
            // 请求完成
            if (this.status === 200) {
                // 返回200
                var blob = this.response;
                var reader = new FileReader();
                reader.readAsDataURL(blob);    // 转换为base64,可以直接放入a
                reader.onload = function (e) {
                    // 转换完成,创建一个a标签用于下载
                    var a = document.createElement('a');
                    a.download = fileName;
                    a.href = e.target.result;
                    $("body").append(a);    // 修复firefox中无法触发click
                    a.click();
                    $(a).remove();
                }
            }
        };
        // 发送ajax请求
        xhr.send()
    }

xxPage.ashx.cs:

    #region  下载日志文件
        public void logFileDownload(HttpContext context)
        {
            string json = string.Empty;
            //获取前台参数
            var logDate = Convert.ToString(context.Request.Params["logDate"]);
            string URLAddress = System.Web.Hosting.HostingEnvironment.MapPath(@"~/logs/" + logDate);

            try
            {
                using (FileStream fs = new FileStream(URLAddress, FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite))
                {
                    using (StreamReader sr = new StreamReader(fs, Encoding.GetEncoding("gb2312")))
                    {
                        json = sr.ReadToEnd().ToString();
                    }
                }

                context.Response.Write(json);

                //停止Response后续写入动作,保证Response内只有我们写入内容
                context.Response.End();
            }
            catch (Exception ex)
            {
                throw;

            }
        }
        #endregion

到这里需求就完成了,关于文件流转成json中文乱码的问题,解决很简单,就是在StreamReader创建时指定编码格式就好,使用Encoding.GetEncoding(“utf-8”)出现乱码的时候,一般改为Encoding.GetEncoding(“gb2312”)即可解决。

另外再写点多余的,也有一种需求是下载远程服务器文件到本机,这和上面的需求是不一样的:

  • 这个需求是项目部署在本机,获取远程服务器文件到本机,可以使用WebClient来实现这个功能;
  • 而上面的是项目部署在服务器,获取服务器文件到本机,需要使用ajax来实现下载。

关于WebClient获取远程地址文件的文章有很多,使用也很简单,如果有兴趣可自行查询。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值