• 通过ftp同步服务器文件:遍历文件夹所有文件(含子文件夹、进度条);简单http同步服务器文件实例


             该代码主要实现,指定ftp服务地址,遍历下载该地址下所有文件(含子文件夹下文件),并提供进度条显示;另外附带有通过http地址方式获取服务器文件的简单实例

    废话不多说,直接上代码:

    1、FTPHelper类

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text;
    
    namespace FileBackup.FTP
    {
        /// <summary>
        /// FTP服务器文件处理
        /// </summary>
        public class FTPHelper
        {
            private string _path;        //ftp服务地址
            private bool _isAuth;        //是否需要身份验证
            private string _userName;    //用户名
            private string _password;    //密码
    
    
            public FTPHelper(string path, bool isAuth, string userName, string password)
            {
                _path = path;
                _isAuth = isAuth;
                _userName = userName;
                _password = password;
            }
    
      /// <summary>
            /// 获取ftp路径地址下文件/文件夹
            /// </summary>
            /// <param name="relativePath">相对于ftp服务地址的路径(相对路径);不传参则代表获取ftp服务地址根目录</param>
            /// <param name="isFloder">1、不传参:获取文件和文件夹;2、true:仅获取文件夹;3、false:仅获取文件</param>
            /// <returns></returns>
            public List<string> GetFileList(string relativePath = null, bool? isFloder = null)
            {
                List<string> result = new List<string>();
                FtpWebRequest request;
                try
                {
                    string path = _path;
                    if (!string.IsNullOrEmpty(relativePath))
                    {
                        path += relativePath;
                    }
    request = (FtpWebRequest)FtpWebRequest.Create(new Uri(path));           
                    request.UseBinary = true;                                               //指定文件以二进制方式传输
                    //是否需要身份验证
                    if (!_isAuth)
                    {
                        request.Credentials = new NetworkCredential();
                    }
                    else
                    {
                        //设置用户名和密码
                        request.Credentials = new NetworkCredential(_userName, _password);
                    }
                    //设置ftp的命令
                    if (isFloder.HasValue)
                    {
                        //仅获取列表
                        request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                    }
                    else
                    {
                        //获取详情(仅获取详情时可以区分文件和文件夹)
                        request.Method = WebRequestMethods.Ftp.ListDirectory;
                    }
    WebResponse response = request.GetResponse();
                    StreamReader reader = new StreamReader(response.GetResponseStream());
                    string line = reader.ReadLine();
                    while (line != null)
                    {
                        //是否区分文件夹/文件读取文件;若不区分,文件夹及文件会一起读取
                        if (isFloder.HasValue)
                        {
                            //仅读取文件夹
                            if ((bool)isFloder)
                            {
                                if (line.Contains("<DIR>"))
                                {
                                    result.Add(line.Substring(line.LastIndexOf("<DIR>") + 5).Trim());
                                }
                            }
     else
                            {
                                //读取文件夹下文件
                                if (!line.Contains("<DIR>"))
                                {
                                    result.Add(line.Substring(39).Trim());
                                }
                            }
                        }
                        else
                        {
                            result.Add(line.Trim());
                        }
                        //读取下一行
                        line = reader.ReadLine();
                    }
                    reader.Close();
                    response.Close();
                    return result;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("get the files/folders from the ftp:" + ex.Message);
                }
                return null;
            }
    
     /// <summary>  
            /// 从FTP服务器下载文件,指定本地路径和本地文件名(支持断点下载)  
            /// </summary>  
            /// <param name="relativePath">远程文件名</param>  
            /// <param name="localFileName">保存本地的文件名(包含路径)</param>  
            /// <param name="size">已下载文件流大小</param>  
            /// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>  
            /// <returns>是否下载成功</returns>  
            public bool FtpBrokenDownload(string relativePath, string localFileName, long size, Action<string, int, int, int> updateProgress = null, int? index = null)
            {
                FtpWebRequest reqFTP, ftpsize;
                Stream ftpStream = null;
                FtpWebResponse response = null;
                FileStream outputStream = null;
                try
                {
                    string path = _path;
                    if (!string.IsNullOrEmpty(relativePath))
                    {
                        path += relativePath;
                    }
    outputStream = new FileStream(localFileName, FileMode.Append);
                    ftpsize = (FtpWebRequest)FtpWebRequest.Create(path);
                    ftpsize.UseBinary = true;
                    ftpsize.ContentOffset = size;
    
                    reqFTP = (FtpWebRequest)FtpWebRequest.Create(path);
                    reqFTP.UseBinary = true;
                    reqFTP.KeepAlive = false;
                    reqFTP.ContentOffset = size;
                    if (_isAuth)//使用用户身份认证  
                    {
                        ftpsize.Credentials = new NetworkCredential(_userName, _password);
                        reqFTP.Credentials = new NetworkCredential(_userName, _password);
                    }
                    ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
                    FtpWebResponse re = (FtpWebResponse)ftpsize.GetResponse();
                    long totalBytes = re.ContentLength;
                    re.Close();
    reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
                    response = (FtpWebResponse)reqFTP.GetResponse();
                    ftpStream = response.GetResponseStream();
    
                    //更新进度    
                    if (updateProgress != null)
                    {
                        updateProgress(localFileName.Substring(localFileName.LastIndexOf('\') + 1, localFileName.Length - localFileName.LastIndexOf('\') -1), (int)totalBytes, 0, (int)index);//更新进度条     
                    }
                    long totalDownloadedByte = 0;
                    int bufferSize = 2048;
                    int readCount;
                    byte[] buffer = new byte[bufferSize];
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
     while (readCount > 0)
                    {
                        totalDownloadedByte = readCount + totalDownloadedByte;
                        outputStream.Write(buffer, 0, readCount);
                        //更新进度    
                        if (updateProgress != null)
                        {
                            updateProgress(localFileName.Substring(localFileName.LastIndexOf('\') + 1, localFileName.Length - localFileName.LastIndexOf('\') -1),(int)totalBytes, (int)totalDownloadedByte, (int)index);//更新进度条     
                        }
                        readCount = ftpStream.Read(buffer, 0, bufferSize);
                    }
                    ftpStream.Close();
                    outputStream.Close();
                    response.Close();
                    return true;
    }
                catch (Exception ex)
                {
                    return false;
                    throw;
                }
                finally
                {
                    if (ftpStream != null)
                    {
                        ftpStream.Close();
                    }
                    if (outputStream != null)
                    {
                        outputStream.Close();
                    }
                    if (response != null)
                    {
                        response.Close();
                    }
                }
            }
        }
    }
    

    2、HttpHelper类

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text;
    
    namespace FileBackup.Http
    {
        public class HttpFileHelper
        {
            /// <summary>
            /// 文件下载(支持断点续传)
            /// </summary>
            /// <param name="httpPath"></param>
            /// <param name="saveFilePath"></param>
            /// <returns></returns>
            public bool DownLoadFiles(string httpPath, string saveFilePath)
            {
                bool flag = false;
                //打开上次下载的文件
                long SPosition = 0;
                //实例化流对象
                FileStream FStream;
     //判断要下载的文件夹是否存在
                if (File.Exists(saveFilePath))
                {
                    //打开要下载的文件
                    FStream = File.OpenWrite(saveFilePath);
                    //获取已经下载的长度
                    SPosition = FStream.Length;
                    long serverFileLength = GetHttpLength(httpPath);
                    //文件是完整的,直接结束下载任务
                    if (SPosition == serverFileLength)
                    {
                        return true;
                    }
                    FStream.Seek(SPosition, SeekOrigin.Current);
                }
                else
                {
                    //文件不保存创建一个文件
                    FStream = new FileStream(saveFilePath, FileMode.Create);
                    SPosition = 0;
                }
                try
                {
                    //打开网络连接
    HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(httpPath);
                    if (SPosition > 0)
                        myRequest.AddRange((int)SPosition);             //设置Range值
                    //向服务器请求,获得服务器的回应数据流
                    Stream myStream = myRequest.GetResponse().GetResponseStream();
                    //定义一个字节数据
                    byte[] btContent = new byte[512];
                    int intSize = 0;
                    intSize = myStream.Read(btContent, 0, 512);
                    while (intSize > 0)
                    {
                        FStream.Write(btContent, 0, intSize);
                        intSize = myStream.Read(btContent, 0, 512);
                    }
                    //关闭流
                    FStream.Close();
                    myStream.Close();
                    flag = true; 
                }
                catch (Exception)
                {
                    FStream.Close();
                    flag = false; 
                }
                return flag;
            }
    /// <summary>
            /// 获取http服务器端文件大小
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            private long GetHttpLength(string url)
            {
                long length = 0;
                try
                {
                    var req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
                    req.Method = "HEAD";
                    req.Timeout = 5000;
                    var res = (HttpWebResponse)req.GetResponse();
                    if (res.StatusCode == HttpStatusCode.OK)
                    {
                        length = res.ContentLength;
                    }
                    res.Close();
                    return length;
                }
                catch (WebException ex)
                {
                    return 0;
                }
            }
        }
    }
    

    3、测试类(Program.cs)

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.IO;
    using System.Net;
    using FileBackup.Http;
    
    namespace FileBackup
    {
        class Program
        {
            //文件序号(递增)
            static int index = 0;
    
            static void Main(string[] args)
            {
     Console.WriteLine("Loading........");
    
                string path = "ftp://xxx.xxx.xxx.xxx:8765/";
                //路径结尾不需要带斜杠
                string localPath = @"E:FTPTestFiles";
                localPath = localPath.TrimEnd('\');
    
                //初始化ftp服务链接
                FTPHelper fTPHelper = new FTPHelper(path, false, null, null);
    
                //获取ftp根目录下所有文件
                List<string> fileList = fTPHelper.GetFileList(null, false);
                if (fileList != null)
                {
                    //路径不存在则创建
                    if (!Directory.Exists(localPath))
                    {
                        Directory.CreateDirectory(localPath);
                    }
    
                    //下载文件到指定本地路径
                    for (int i = 0; i < fileList.Count; i++)
                    {
                        Action<string, int, int, int> action = new Action<string, int, int, int>(ShowAction);
                        index++;
                        fTPHelper.FtpBrokenDownload(fileList[i], string.Format(@"{0}{1}", localPath, fileList[i]), 0, action, index);
                    }
                }
    
                //获取ftp根目录下所有文件夹
                List<string> dirctoryList = fTPHelper.GetFileList(null, true);
                if (dirctoryList != null)
                {
                    //递归下载文件夹下所有文件(初始父级相对路径为空)
                    FilesDownLoad(fTPHelper, dirctoryList, null, localPath);
                }
    
                //http文件下载测试
                HttpFileHelper httpFileHelper = new HttpFileHelper();
                httpFileHelper.DownLoadFiles("http://xxxxxxx:9798/upload/190125122251440.docx", string.Format(@"{0}{1}", localPath, "httpfile.docx"));
    
                Console.WriteLine("End........");
    
                Console.ReadLine();
            }
    /// <summary>
            /// 下载文件夹列表下的所有文件(自动创建对应文件夹)
            /// </summary>
            /// <param name="fTPHelper"></param>
            /// <param name="dirctoryList">文件夹列表</param>
            /// <param name="parentRelativePath">ftp父级相对路径</param>
            /// <param name="localPath">本地存放路径</param>
            private static void FilesDownLoad(FTP.FTPHelper fTPHelper, List<string> dirctoryList, string parentRelativePath, string localPath)
            {
                if (dirctoryList != null)
                {
                    for (int i = 0; i < dirctoryList.Count; i++)
                    {
                        //当前本地下载路径
                        string localCurPath = string.Format(@"{0}{1}", localPath, dirctoryList[i]); ;
                        //当前ftp相对路径
                        string ftpCurPath = dirctoryList[i];
    if (!string.IsNullOrEmpty(parentRelativePath))
                        {
                            ftpCurPath = string.Format(@"{0}{1}", parentRelativePath, dirctoryList[i]);
                        }
                        //路径不存在则创建
                        if (!Directory.Exists(localCurPath))
                        {
                            Directory.CreateDirectory(localCurPath);
                        }
    
                        //获取文件夹下所有文件
                        List<string> subfileList = fTPHelper.GetFileList(ftpCurPath, false);
    if(subfileList != null)
                        {
                            for (int j = 0; j < subfileList.Count; j++)
                            {
                                //下载文件夹下所有文件,文件名与ftp服务器上文件名保持一致(含后缀)
                                Action<string, int, int, int> action = new Action<string, int, int, int>(ShowAction);
                                index++;
                                fTPHelper.FtpBrokenDownload(string.Format(@"{0}{1}", ftpCurPath, subfileList[j]), string.Format(@"{0}{1}", localCurPath, subfileList[j]), 0, action, index);
                            }
                        }
    
                        //获取该文件夹下所有子文件夹
                        List<string> subdirctoryList = fTPHelper.GetFileList(ftpCurPath, true);
                        if (subdirctoryList != null)
                        {
                            //递归下载文件夹下所有文件
                            FilesDownLoad(fTPHelper, subdirctoryList, ftpCurPath, localCurPath);
                        }
                    }
                }
            }
    
    /// <summary>
            /// 控制台进度显示
            /// </summary>
            /// <param name="file"></param>
            /// <param name="size"></param>
            /// <param name="progress"></param>
            /// <param name="rowIndex"></param>
            public static void ShowAction(string file, int size, int progress, int rowIndex)
            {
                //命令行光标位置定位
                Console.SetCursorPosition(0, rowIndex);
                if (size > 0)
                {
                    Console.WriteLine(string.Format("{0}: Total Size:{1}; Progress:{2}%", file, size, Math.Round((Double)progress*100 / (Double)size, 0)));
                }
    else
                {
                    Console.WriteLine(string.Format("{0}: Total Size:{1}; Progress:{2}%", file, size, 100));
                }
            }
        }
    }
  • 相关阅读:
    《Docker Deep Dive》Note
    使用 Angular RouteReuseStrategy 缓存(路由)组件
    我的 VSCode 配置
    TCP/IP协议
    Fiddler代理手机抓包
    基于 Docker 和 GitLab 的前端自动化部署实践笔记
    Vue.js 2.x render 渲染函数 & JSX
    服务器免密登陆脚本
    gitlab+jenkins+pm2+rsync实现node的自动化部署
    nginx常用
  • 原文地址:https://www.cnblogs.com/wanggang2016/p/10334819.html
Copyright © 2020-2023  润新知