该代码主要实现,指定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));
}
}
}
}

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

  1. jQuery文件上传插件jQuery Upload File 有上传进度条

    jQuery文件上传插件jQuery Upload File 有上传进度条 jQuery文件上传插件jQuery Upload File,插件使用简单,支持单文件和多文件上传,支持文件拖拽上传,有进度 ...

  2. asp.net(c#)开发中的文件上传组件uploadify的使用方法(带进度条)

    上文件传很常见,现在就文件上传利用HTML的File控件(uploadify)的,这里为大家介绍一下(uploadify)的一些使用方法.在目前Web开发中用的比较多的,可能uploadify(参考h ...

  3. iOS带动画的环形进度条(进度条和数字同步)

    本篇写的是实现环形进度条,并带动画效果,要实现这些,仅能通过自己画一个 方法直接看代码 为了方便多次调用,用继承UIView的方式 .m文件 #import <UIKit/UIKit.h> ...

  4. ajax +formdata ,后台为PHP 实现上传整个文件夹(只适合谷歌浏览器)带进度条

    PHP用超级全局变量数组$_FILES来记录文件上传相关信息的. 1.file_uploads=on/off 是否允许通过http方式上传文件 2.max_execution_time=30 允许脚本 ...

  5. Python 中当前位置以及目录文件遍历操作

    Python 中当前位置以及目录文件遍历操作 当前位置 print(os.path.dirname(__file__)) 其中 dirname 会选择目录(文件夹),"__file__&qu ...

  6. atitit.文件上传带进度条的实现原理and组件选型and最佳实践总结O7

    atitit.文件上传带进度条的实现原理and组件选型and最佳实践总结O7 1. 实现原理 1 2. 大的文件上传原理::使用applet 1 3. 新的bp 2 1. 性能提升---分割小文件上传 ...

  7. php上传文件进度条

    ps:本文转自脚本之家 Web应用中常需要提供文件上传的功能.典型的场景包括用户头像上传.相册图片上传等.当需要上传的文件比较大的时候,提供一个显示上传进度的进度条就很有必要了. 在PHP 5.4以前 ...

  8. PHP中使用Session配合Javascript实现文件上传进度条功能

    Web应用中常需要提供文件上传的功能.典型的场景包括用户头像上传.相册图片上传等.当需要上传的文件比较大的时候,提供一个显示上传进度的进度条就很有必要了. 在PHP .4以前,实现这样的进度条并不容易 ...

  9. Flex4/Flash多文件上传(带进度条)实例分享

    要求 必备知识 本文要求基本了解 Adobe Flex编程知识和JAVA基础知识. 开发环境 MyEclipse10/Flash Builder4.6/Flash Player11及以上 演示地址 演 ...

随机推荐

  1. November 20th 2016 Week 47th Sunday

    Learn from yesterday, live for today, look to tomorrow. 学习昨天,活在今天,展望明天. There is always room at the ...

  2. November 5th Week 45th Saturday 2016

    The longest day has an end. 最难过的日子也会有尽头. No, no, no, I can't see the end of such days, of course, if ...

  3. PAT 1001 A+B 解题报告

    PAT 1001 A+B 代码链接:传送门 题目链接:传送门 题目简述: 给定两个值a,b: 范围-1000000 <= a, b <= 1000000: 按指定格式输出a+b的结果,例: ...

  4. Connection:Keep-alive

    名词解释: HTTP无状态:无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态.从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系 如果你要实现一个购 ...

  5. 常见dos命令(win7下测试)

    按下组合键:win + R ,输入cmd进入Dos. 1.  cls :清屏命令. 2.  ver :查看系统版本号命令,winver弹出一个窗口显示更详细的系统版本号. 3.  dir  无参数 : ...

  6. C++中重载决议与可访问性检查的顺序

    http://blog.csdn.net/starlee/article/details/1406781 对于如下的类: class ClxECS{public:    double Test(dou ...

  7. SharePoint 改动passwordWeb Part部署方案

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u012025054/article/details/31773231 SharePoint 改动pa ...

  8. Sequelize-nodejs-10-Hooks

    Hooks钩子 Hooks (also known as lifecycle events), are functions which are called before and after call ...

  9. NSPredicate的使用

    简述 NSPredicate谓词条件过滤器,一般用于过滤数组数据,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取. 常用函数 创建谓词 + (NSPredicate *)predic ...

  10. C语言程序设计I—第十二周教学

    第十二周教学总结(19/11-25/11) 教学内容 第4章 循环结构 4.5 循环结构程序设计 课前准备 在蓝墨云班课发布资源: PTA:2018秋第十二周作业4.5 分享码:B7FA52A13B6 ...