通過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));
            }
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM