上篇文章讨论了C#从基于FTPS的FTP server下载数据 (FtpWebRequest 的使用)SSL 加密。不过细心的朋友应该可以发现FTPWebRequest 每次都是新生成一个request ( FTPWebRequest.create(uri) ), 这样对于一些复杂的需求,需要反复登陆,代码就会变得冗余啰嗦,那今天就和大家探讨一下如何包装FTPWebRequest类。如有好的想法或意见,希望各位大神老鸟多多指教。

 
先说一下我的需求:
 
去FTP Server 的一个指定路径下,找到更新时间最近的文件并下载。
那按照以上需求,就需要先去路径下,找到更新时间最近的文件,在根据文件名下载。 
 
这里封装一个FTPClient 类 (从网上找了一个FTPClient的壳子,忘记了原博客地址了,抱歉)
原理很简单,就是封装‘列出目录功能’和 ‘下载文件功能’。将用户名密码等放在FTPClient的属性中。
上码!
 
 using System.Collections.Generic;
using System;
using System.Net;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security; namespace FtpClientBlogCase
{ #region "FTP client class"
public class FTPclient
{
#region "CONSTRUCTORS"
public FTPclient(string Hostname, string Username, string Password, bool EnableSSL)
{
this.Hostname = Hostname;
this.Username = Username;
this.Password = Password;
this.EnableSsl = EnableSSL;
}
#endregion #region "Directory functions"
public List<string> ListDirectory(string URI)
{
System.Net.FtpWebRequest ftp = GetRequest(URI);
//Set request to do simple list
ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectory; string str = GetStringResponse(ftp);
//replace CRLF to CR, remove last instance
str = str.Replace("\r\n", "\r").TrimEnd('\r');
//split the string into a list
List<string> result = new List<string>();
result.AddRange(str.Split('\r'));
return result;
}
#endregion #region "Download: File transfer FROM ftp server"
/// <summary>
/// Copy a file from FTP server to local
/// </summary>
/// <param name="sourceFilename">Target filename, if required</param>
/// <param name="localFilename">Full path of the local file</param>
/// <returns></returns>
/// <remarks>
/// Target can be blank (use same filename), or just a filename
/// (assumes current directory) or a full path and filename
/// 1.2 [HR] added CreateURI
/// </remarks>
public bool Download(string sourceFilename, string localFilename, bool PermitOverwrite)
{
//2. determine target file
FileInfo fi = new FileInfo(localFilename);
return this.Download(sourceFilename, fi, PermitOverwrite);
} /// <summary>
/// Version taking string/FileInfo
/// </summary>
/// <param name="sourceFilename"></param>
/// <param name="targetFI"></param>
/// <param name="PermitOverwrite"></param>
/// <returns></returns>
public bool Download(string sourceFilename, FileInfo targetFI, bool PermitOverwrite)
{
//1. check target
if (targetFI.Exists && !(PermitOverwrite))
{
throw (new ApplicationException("Target file already exists"));
} //2. check source
if (String.IsNullOrEmpty(sourceFilename))
{
throw (new ApplicationException("File not specified"));
}
System.Net.FtpWebRequest ftp = GetRequest(sourceFilename); //Set request to download a file in binary mode
ftp.Method = System.Net.WebRequestMethods.Ftp.DownloadFile;
ftp.UseBinary = true; //open request and get response stream
using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
//loop to read & write to file
responseStream.ReadTimeout = ;
using (FileStream fs = targetFI.OpenWrite())
{
try
{
byte[] buffer = new byte[**];
int read = ;
do
{
read = responseStream.Read(buffer, , buffer.Length);
fs.Write(buffer, , read);
fs.Flush();
} while (read != );
responseStream.Close();
fs.Flush();
fs.Close();
}
catch (Exception)
{
//catch error and delete file only partially downloaded
fs.Close();
//delete target file as it's incomplete
targetFI.Delete();
throw;
}
} responseStream.Close();
} response.Close();
} return true;
} #endregion #region "private supporting fns" //Get the basic FtpWebRequest object with the
//common settings and security
private FtpWebRequest GetRequest(string URI)
{
//create request
FtpWebRequest result = (FtpWebRequest)FtpWebRequest.Create(URI);
//Set the login details
result.Credentials = GetCredentials();
// support for EnableSSL
result.EnableSsl = EnableSsl;
result.Timeout = ; ServicePoint sp = result.ServicePoint;
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(ValidateServerCertificate); return result;
} /// <summary>
/// Ensure chars in path are correctly escaped e.g. #
/// </summary>
/// <param name="path">path to escape</param>
/// <returns></returns>
private string GetEscapedPath(string path)
{
string[] parts;
parts = path.Split('/');
string result;
result = "";
foreach (string part in parts)
{
if (!string.IsNullOrEmpty(part))
result += @"/" + Uri.EscapeDataString(part);
}
return result;
} /// <summary>
/// Get the credentials from username/password
/// </summary>
/// <remarks>
/// Amended to store credentials on first use, for re-use
/// when using KeepAlive=true
/// </remarks>
private System.Net.ICredentials GetCredentials()
{
if (_credentials == null)
_credentials = new System.Net.NetworkCredential(Username, Password);
return _credentials;
} /// <summary>
/// stored credentials
/// </summary>
private System.Net.NetworkCredential _credentials = null; /// <summary>
/// Obtains a response stream as a string
/// </summary>
/// <param name="ftp">current FTP request</param>
/// <returns>String containing response</returns>
/// <remarks>
/// FTP servers typically return strings with CR and
/// not CRLF. Use respons.Replace(vbCR, vbCRLF) to convert
/// to an MSDOS string
/// 1.1: modified to ensure accepts UTF8 encoding
/// </remarks>
private string GetStringResponse(FtpWebRequest ftp)
{
//Get the result, streaming to a string
string result = "";
using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
{
long size = response.ContentLength;
using (Stream datastream = response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(datastream, System.Text.Encoding.UTF8))
{
result = sr.ReadToEnd();
sr.Close();
} datastream.Close();
} response.Close();
} return result;
} /// <summary>
/// Gets the size of an FTP request
/// </summary>
/// <param name="ftp"></param>
/// <returns></returns>
/// <remarks></remarks>
private long GetSize(FtpWebRequest ftp)
{
long size;
using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
{
size = response.ContentLength;
response.Close();
} return size;
} private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
} #endregion #region Properties public string Hostname { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public bool EnableSsl { get; set; } #endregion }
#endregion }

FTPClient.cs

 using System;
using System.Configuration;
using System.Linq; namespace FtpClientBlogCase
{
class Program
{
static void Main(string[] args)
{
DownloadFileFromFTP.DownloadFileFromNetwork();
Console.WriteLine("Done");
}
} public class DownloadFileFromFTP
{
public static void DownloadFileFromNetwork()
{
var fullDataServer = "XXX";
var userName = "XXX";
var password = "XXX";
var fc = new FTPclient(fullDataServer, userName, password, true);
var list = fc.ListDirectory(fullDataServer);
Console.WriteLine("The file is downloading, please wait...");
fc.Download(fullDataServer + list.Last(), list.Last(), true); }
}
}

Program.cs

在类FTPClient中,private FtpWebRequest GetRequest(string URI) 是最重要的方法,它为每一个功能提供了一个FtpWebRequest对象,避免了每次生成request对象的冗余冗余代码。

包装FTPWebRequest类的更多相关文章

  1. 【自制工具类】struts返回json数据包装格式类

    自己写的一个给struts返回的json数据包装格式类,不喜勿喷,原创,需在项目中引入com.alibaba.fastjson的jar包 先看下效果(这里没有使用msg,有兴趣的往下看): 上demo ...

  2. java基本类型和包装器类

    java是一种面向对象语言,java中的类把方法与数据连接在一起,并构成了自包含式的处理单元.但在java中不能定义基本类型(primitive type),为了能将基本类型视为对象来处理,并能连接相 ...

  3. 走近Java之包装器类Integer

    前几天,有个同事问了我一个关于Integer类赋值的问题,很有意思,我们一起来看一下(如果有说的不正确的地方,欢迎大家指正). 如上图,同样是赋值,但是两次比较的结果完全不同.我们走近了解一下. 在I ...

  4. 课堂所讲整理:包装&工具类

    package org.hanqi.array; import java.util.Random; public class BaoZhuang { public static void main(S ...

  5. 用于JS日期格式化,以及简单运算的Date包装工具类

    1. [文件] yDate.js/** * | yDate.js | Copyright (c) 2013 yao.yl | email: redrainyi@126.com | Date: 2012 ...

  6. Python-面向对象(类)一

    一.如何创建类 class cls: pass 二.创建方法 构造方法: __init__(self, arg) obj = 类('a1') 普通方法: obj = 类('xxx') obj.普通方法 ...

  7. Spring源码分析——资源访问利器Resource之实现类分析

    今天来分析Spring的资源接口Resource的各个实现类.关于它的接口和抽象类,参见上一篇博文——Spring源码分析——资源访问利器Resource之接口和抽象类分析 一.文件系统资源 File ...

  8. 在C#中使用C++编写的类

    现在在Windows下的应用程序开发,VS.Net占据了绝大多数的份额.因此很多以前搞VC++开发的人都转向用更强大的VS.Net.在这种情况下,有很多开发人员就面临了如何在C#中使用C++开发好的类 ...

  9. Python全栈--9.1--面向对象进阶-super 类对象成员--类属性- 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理

    上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...

随机推荐

  1. Python re 正则表达式简介

    1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十 ...

  2. websoket使用Protocol Buffers3.0传输

    Protocol Buffers是Google推出的一个数据交换格式,相对于xml它的体积更小,更快,因为它是二进制传输的.3.0相对于2.0变动比较大.这些变动可以去看官方说明. 在前端使用Prot ...

  3. stl_container容器和std_algorithm算法相同的函数

    八.算法和容器中存在的功能相同的函数: 8.1.array: 8.1.1.fill. 1.在array中:void fill (const value_type& val); 2.在algor ...

  4. Omi树组件omi-tree编写指南

    Omi框架能够以少量的代码声明式地编写可拖拽移动节点的树形组件. 通常树组件能够考验UI框架的健壮性,因为需要使用到UI框架的如下特性: 组件嵌套 组件传值 组件批量传值 组件依赖自身递归嵌套(nes ...

  5. Redhat 安装ftp服务

    介绍: 1 安装ftp服务端及客户端 2 ftp的使用

  6. Gym - 101102C线段树

    Judge Bahosain was bored at ACM AmrahCPC 2016 as the winner of the contest had the first rank from t ...

  7. 在android中,如何去掉webview读取网页后点击网页上的按钮出现的方框

    参考:http://blog.sina.com.cn/s/blog_64056edc0100xt3l.html <style type="text/css"> .bor ...

  8. TPshop分销功能的使用与表设计

    首先来段科普,摘自百度百科: 在西方经济学中,分销 的含义是建立销售渠道的意思,根据著名的营销大师菲利普·科特勒的定义,分销渠道(Distribution Channel)又或者叫营销渠道(Marke ...

  9. poj2481 Cows 树状数组

    题目链接:http://poj.org/problem?id=2481 解题思路: 这道题对每组数据进行查询,是树状数组的应用.对于二维的树状数组, 首先想到排序.现在对输入的数据按右值从大到小排序, ...

  10. 版本管理工具SVN学习(一):简单的SVN命令,兼对比Git

    新公司用SVN来管理代码,而且公司自己搭建了SVN服务器,所以要学习下SVN的相关命令.服务器搭建等技能知识.上家公司是用Git管理代码,而且代码托管在git@oschina上,自然不用操心Git服务 ...