FtpWebRequest FTP异步下载、异步上传文件
异步下载:
public interface IPrimaryKey<T>
{
T GetKey();
} public class DownloadInfo : IPrimaryKey<string>
{
public string FtpResourceFilePath { get; set; } public string FileSaveLocalPath { get; set; } public bool IsDir { get; set; } public DateTime StartTime { get; set; } public int ProgressPercentage { get; set; } public string Speed { get; set; } public string GetKey()
{
return this.FtpResourceFilePath;
} public List<DownloadInfo> SubFiles { get; set; }
}
class Program
{
static readonly string FTP_USERNAME = string.Empty;
static readonly string FTP_PASSWORD = string.Empty;
static readonly string FTP_DOMAIN = string.Empty;
// default 1 seconds.
static readonly int FTP_REQUEST_TIMEOUT = ;
// default 1 seconds.
static readonly int FTP_REQUEST_READWRITERTIMEOUT = ; static Program()
{
FTP_REQUEST_TIMEOUT = Convert.ToInt32(ConfigurationManager.AppSettings.Get("FTP.Request.Timeout"));
FTP_REQUEST_READWRITERTIMEOUT = Convert.ToInt32(ConfigurationManager.AppSettings.Get("FTP.Request.ReadWriteTimeout"));
FTP_USERNAME = ConfigurationManager.AppSettings.Get("FTP.UserName");
FTP_PASSWORD = ConfigurationManager.AppSettings.Get("FTP.Password");
FTP_DOMAIN = ConfigurationManager.AppSettings.Get("FTP.Domain");
} static int DownloadCount = ;
static int CompleteCount = ; static void Main(string[] args)
{
// default max parallel connection count is two in the .net framework.
// sugesstion no over 1024.
// and you also can add config node in app.config
/* <configuration>
* <system.net>
* <connectionManagement>
* <add address="*" maxconnection="512"/>
* </connectionManagement>
* </system>
* </configuration>
*/
//System.Net.ServicePointManager.DefaultConnectionLimit = 512; string localRootPath = ConfigurationManager.AppSettings.Get("SaveRootPath"); List<DownloadInfo> rootFiles = GetSubFilesList(new DownloadInfo()
{
FtpResourceFilePath = "ftp://172.21.3.17//dd/MR",
FileSaveLocalPath = string.Concat(localRootPath, "~TEMP\\Test1")
}); DownloadFilesAsync(rootFiles); Console.ReadKey();
} private static void DownloadFilesAsync(List<DownloadInfo> items)
{
foreach (DownloadInfo task in items)
{
task.StartTime = DateTime.Now; if (task.IsDir)
{
task.SubFiles = GetSubFilesList(task); DownloadFilesAsync(task.SubFiles);
}
else
{
// try create the directory before donwload.
TryCreateDirectory(task.FileSaveLocalPath); // Uri :the resource paht which will be download.
// fileName :the dowload file save path;
CreateWebClient().DownloadFileAsync(new Uri(task.FtpResourceFilePath), task.FileSaveLocalPath, task);
}
}
} static WebClient CreateWebClient()
{
// 限制最多同时现在的线程数
LimitThreadAgain:
if (DownloadCount - CompleteCount > )
{
Thread.Sleep(); goto LimitThreadAgain;
} DownloadCount++; WebClient client = new WebClient();
client.Credentials = new NetworkCredential(FTP_USERNAME, FTP_PASSWORD, FTP_DOMAIN);
client.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); return client;
} private static List<DownloadInfo> GetSubFilesList(DownloadInfo task)
{
List<DownloadInfo> subFiles = new List<DownloadInfo>(); FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(task.FtpResourceFilePath));
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.Credentials = new NetworkCredential(FTP_USERNAME, FTP_PASSWORD, FTP_DOMAIN);
request.UseBinary = true;
request.Timeout = FTP_REQUEST_TIMEOUT;
request.ReadWriteTimeout = FTP_REQUEST_READWRITERTIMEOUT; using (WebResponse response = request.GetResponse())
{
using (StreamReader responseStream = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default))
{
string line = responseStream.ReadLine();
while (line != null)
{
Console.WriteLine(line); string[] lineParitialArray = line.Split(new char[] { ' ' });
string theName = lineParitialArray[lineParitialArray.Length - ]; if (line.IndexOf("<DIR>") != -)
{
subFiles.Add(new DownloadInfo()
{
FtpResourceFilePath = string.Concat(task.FtpResourceFilePath, "/", theName),
FileSaveLocalPath = string.Concat(task.FileSaveLocalPath, "\\", theName),
IsDir = true
});
}
else
{
subFiles.Add(new DownloadInfo()
{
FtpResourceFilePath = string.Concat(task.FtpResourceFilePath, "/", theName),
FileSaveLocalPath = string.Concat(task.FileSaveLocalPath, "\\", theName),
IsDir = false
});
} line = responseStream.ReadLine();
}
}
} return subFiles;
} static void TryCreateDirectory(string filePath)
{
FileInfo fileInfo = new FileInfo(filePath);
if (!fileInfo.Directory.Exists)
{
try
{
fileInfo.Directory.Create();
}
catch (Exception ex)
{
Logger.Current.Error("an error thrown while create directory:\r\n{0}\r\n{1}", ex.Message, ex.StackTrace);
}
}
} static void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
DownloadInfo downloadInfo = e.UserState as DownloadInfo; downloadInfo.ProgressPercentage = e.ProgressPercentage;
double downloadTime = (DateTime.Now - downloadInfo.StartTime).TotalSeconds;
downloadInfo.Speed = GetFriendlyFileSize(e.BytesReceived / downloadTime, ); Console.WriteLine("download precentage:{0}-{1}-{2}", downloadInfo.ProgressPercentage, downloadInfo.Speed, downloadInfo.FtpResourceFilePath); Logger.Current.Debug(string.Format("download precentage:{0}-{1}-{2}", downloadInfo.ProgressPercentage, downloadInfo.Speed, downloadInfo.FtpResourceFilePath));
} static void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
if (e.Error.InnerException != null)
Logger.Current.Error(string.Format("download error:{0}\r\n{1}", e.Error.InnerException.Message, e.Error.InnerException.StackTrace));
else
Logger.Current.Error(string.Format("download error:{0}\r\n{1}", e.Error.Message, e.Error.StackTrace));
} DownloadInfo downloadInfo = e.UserState as DownloadInfo; Console.WriteLine("download complete:{0}", downloadInfo.FtpResourceFilePath);
Logger.Current.Debug(string.Format("download complete:{0}", downloadInfo.FtpResourceFilePath)); CompleteCount++;
} const double KB = ;
const double MR = KB * ;
const double GB = MR * ;
const double TB = MR * ;
const double PB = TB * ; static string GetFriendlyFileSize(double size, int decimals)
{
if (KB > size)
return string.Format("{0}B", Math.Round(size, decimals));
else if (MR > size)
return string.Format("{0}KB", Math.Round(size / KB, decimals));
else if (GB > size)
return string.Format("{0}MR", Math.Round(size / MR, decimals));
else if (TB > size)
return string.Format("{0}GB", Math.Round(size / GB, decimals));
else if (PB > size)
return string.Format("{0}TB", Math.Round(size / TB, decimals));
else
return string.Format("{0}PB", Math.Round(size / PB, decimals));
}
}
异步上传:
// uploading
#region uploading public class Program
{
public static void Main(string[] args)
{
FtpState state = new FtpState(); // the ftp url scheme like: ftp://
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri("ftp://172.21.*.1*//dd/SHFBGuidedInstaller_2014.5.31.0.zip"));
request.Method = WebRequestMethods.Ftp.UploadFile;
//request.Method = WebRequestMethods.Ftp.DownloadFile; request.Credentials = new NetworkCredential("dn", "new.1234", "domain"); state.Request = request;
state.FileName = @"C:\Users\dn\Desktop\SHFBGuidedInstaller_2014.5.31.0.zip";
//state.FileName = @"C:\Users\dn\Desktop\MR\SHFBGuidedInstaller_2014.5.31.0.zip"; // 获得WaitOne()对象
ManualResetEvent waitOjbect = state.OperationComplete; // 开始异步获取数据流
request.BeginGetRequestStream(
new AsyncCallback(EndGetStreamCallback),
state
); // 线程等待
waitOjbect.WaitOne(); if (state.OperationException != null)
{
throw state.OperationException;
}
else
{
Console.WriteLine("操作已经完成!");
}
} public class FtpState
{
private ManualResetEvent wait;
private FtpWebRequest request;
private string fileName;
private Exception opreationException = null;
private string statusDescription; public FtpState()
{
wait = new ManualResetEvent(false);
} public ManualResetEvent OperationComplete
{
get { return wait; }
} public FtpWebRequest Request
{
get { return request; }
set { request = value; }
} public string FileName
{
get { return fileName; }
set { fileName = value; }
} public Exception OperationException
{
get { return opreationException; }
set { opreationException = value; }
} public string StatusDescription
{
get { return statusDescription; }
set { statusDescription = value; }
}
} private static void EndGetStreamCallback(IAsyncResult result)
{
FtpState state = (FtpState)result.AsyncState; try
{
using (Stream requestStream = state.Request.EndGetRequestStream(result))
{
const int bufferLength = ;
byte[] buffer = new byte[bufferLength]; int count = ;
int readBytes = ; using (FileStream stream = File.OpenRead(state.FileName))
{
do
{
readBytes = stream.Read(buffer, , bufferLength); requestStream.Write(buffer, , readBytes); count += readBytes;
}
while (readBytes != );
} Console.WriteLine("写入{0}字节到数据流中", count); state.Request.BeginGetResponse(new AsyncCallback(EndGetResponseCallback), state);
}
}
catch (Exception ex)
{
Console.WriteLine("请求数据流失败!"); state.OperationException = ex;
state.OperationComplete.Set();
}
} private static void EndGetResponseCallback(IAsyncResult result)
{
FtpState state = (FtpState)result.AsyncState; try
{
FtpWebResponse response = (FtpWebResponse)state.Request.EndGetResponse(result);
response.Close(); state.StatusDescription = response.StatusDescription;
// 标记主线程结束
state.OperationComplete.Set();
}
catch (Exception ex)
{
Console.WriteLine("获取请求回应失败!");
state.OperationException = ex;
state.OperationComplete.Set();
}
} #endregion
}
FtpWebRequest FTP异步下载、异步上传文件的更多相关文章
- Android中实现异步轮询上传文件
前言 前段时间要求项目中需要实现一个刷卡考勤的功能,因为涉及到上传图片文件,为加快考勤的速度,封装了一个异步轮询上传文件的帮助类 效果 先上效果图 设计思路 数据库使用的框架是GreenDao,一个 ...
- iOS开发——网络Swift篇&NSURLSession加载数据、下载、上传文件
NSURLSession加载数据.下载.上传文件 NSURLSession类支持三种类型的任务:加载数据.下载和上传.下面通过样例分别进行介绍. 1,使用Data Task加载数据 使用全局的 ...
- Swift - 使用NSURLSession加载数据、下载、上传文件
NSURLSession类支持三种类型的任务:加载数据.下载和上传.下面通过样例分别进行介绍. 1,使用Data Task加载数据 使用全局的sharedSession()和dataTaskWithR ...
- Windows下使用PSCP从Linux下载或上传文件
1. 先下载putty包,然后解压 https://the.earth.li/~sgtatham/putty/latest/w64/putty.zip 2. 下载Linux文件到当前目录 PSCP.e ...
- node.js服务器端下载、上传文件
使用request 下载文件: 安装依赖: npm i requestsourceUrl下载源,targetUrl保存路径 async function downLoadFile(sourceUrl, ...
- Linux使用sz、rz命令下载、上传文件
1.安装服务 yum -y install lrzsz 2.上传命令:rz 使用rz命令,会调用系统的资源管理器,选择文件进行上传即可.上传的文件默认保存linux当前所在目录 3.下载命令:sz 根 ...
- Linux服务器下载与上传文件
一.图形化工具 FileZilla.SecureCRT,连接Linux服务器后直接操作 二.命令 使用终端模拟软件连接服务器后,首先安装lrzsz工具包 yum install lrzsz rz ,上 ...
- Webform之FileUpload(上传按钮控件)简单介绍及下载、上传文件时图片预览
1.FileUpload上传控件:(原文:http://www.cnblogs.com/hide0511/archive/2006/09/24/513201.html) FileUpload 控件显示 ...
- 用WebClient在异步下载或上传时每次只进行一个任务 C#
当在每次上传或者下载的时候,我只想进行一个任务的,我用的是WebClient类,但是我又不想用同步的方法UploadFile.DownloadFile,因为WebClient这个类的同步方法没有Upl ...
- ftp如何使用命令上传文件
本地上传到服务器的步骤如下: 1."开始"-"运行"-输入"FTP" 2.open qint.ithot.net 这一步可以与第一步合并,在 ...
随机推荐
- mysql读写分离(PHP类)
mysql读写分离(PHP类) 博客分类: php mysql 自己实现了php的读写分离,并且不用修改程序 优点:实现了读写分离,不依赖服务器硬件配置,并且都是可以配置read服务器,无限扩展 ...
- MVC 扩展方法特点
.NET MVC 3中扩展方法特点: (1)扩展类的名称以Extensions结尾: (2)扩展类的类型是static: (3)扩展方法至少有一个参数,第一个参数必须指定该方法作用于哪个类型,并且该参 ...
- Gender, Genre, and Writing Style in Formal Written Texts
http://u.cs.biu.ac.il/~koppel/papers/male-female-text-final.pdf Abstract. This paper explores di ...
- 使用JSONP跨域请求数据
下面代码,可以使用JSONP进行跨域请求数据,Insus.NET记录以下,以备忘记.
- unity3d中控制物体移动方法有那些及区别
1. 利用GameObject的Translate,直接改变它的Transform,前提是需要你实现准备变换矩阵.2. 用MoveTo方法,你只要知道你的目标位置即可.3. 用Math的Lerp方法计 ...
- jquery easyui Combobox 实现 两级联动
具体效果如下图:
- Qt的IDE开发环境(KDevelop,MonKey Studio,QDevlop,Dev-cpp,Cobras,Edyuk)
讲到Qt的IDE开发环境,本人一直在Windows下使用VC6.0 + Qt4.3.1开发程序.但转到Linux下,使用Fedora中自带的KDevelop + Qt4.3.1开发程序. 最近一直做Q ...
- 转NodeJS的npm模块版本号 模式解析
npm 中的模块版本都需要遵循 semver 2.0 的语义化版本规则. 版本格式:主版本号.次版本号.修订号,版本号递增规则如下: 主版本号:当你做了不兼容的API 修改, 次版本号:当你做了向下兼 ...
- SQL集合函数中利用case when then 技巧
我们都知道SQL中适用case when then来转化数据库中的信息 比如 select (case sex when 0 then '男' else '女' end) AS sex from ...
- QGridLayout--01
#include "mainwindow.h" #include <QApplication> #include<QLabel> #include<Q ...