惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Palo Alto Networks Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
CERT Recently Published Vulnerability Notes
C
Cybersecurity and Infrastructure Security Agency CISA
S
Schneier on Security
S
Securelist
酷 壳 – CoolShell
酷 壳 – CoolShell
C
CXSECURITY Database RSS Feed - CXSecurity.com
Cyberwarzone
Cyberwarzone
Apple Machine Learning Research
Apple Machine Learning Research
S
SegmentFault 最新的问题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
GbyAI
GbyAI
Security Latest
Security Latest
Last Week in AI
Last Week in AI
Microsoft Security Blog
Microsoft Security Blog
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
Webroot Blog
Webroot Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
TaoSecurity Blog
TaoSecurity Blog
C
Cisco Blogs
博客园 - 【当耐特】
Blog — PlanetScale
Blog — PlanetScale
Hugging Face - Blog
Hugging Face - Blog
B
Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Attack and Defense Labs
Attack and Defense Labs
The Last Watchdog
The Last Watchdog
U
Unit 42
阮一峰的网络日志
阮一峰的网络日志
Project Zero
Project Zero
WordPress大学
WordPress大学
L
LINUX DO - 最新话题
F
Fortinet All Blogs
L
LINUX DO - 热门话题
PCI Perspectives
PCI Perspectives
Simon Willison's Weblog
Simon Willison's Weblog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
MongoDB | Blog
MongoDB | Blog
Latest news
Latest news
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
The Hacker News
The Hacker News
爱范儿
爱范儿
O
OpenAI News
J
Java Code Geeks
T
The Exploit Database - CXSecurity.com
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - yunhuasheng

主数据管理和实施 最常见的13种主数据管理(MDM)词汇和定义 构建一个主数据管理(MDM)的解决方案 MDM 介绍二 主数据管理(MDM)的成熟度 MDM 介绍 一 主数据管理(MDM)的七个最佳实践 如何用正确的方法来写出质量好的软件的75条体会 ESB——企业服务总线没有神话 ESB企业服务总线 关于RUP(统一软件开发过程) SQL语言检索表中的字段名 用SQL语句添加删除修改字段、一些表与字段的基本操作、数据库备份等 白盒测试 深入理解抽象类和接口(abstract class vs interface ) 转 www.IBM.com 程序员的十层楼(8~9层) 程序员的十层楼(6~7层) 程序员的十层楼(4~5层) 程序员的十层楼(1~3层) SSO 单点登录及功能实现机制
转载:.net 操作FTP from http://www.cnblogs.com/aierong/archive/2008/12/08/ftp.html
yunhuasheng · 2008-12-08 · via 博客园 - yunhuasheng


最近项目需要对FTP服务器进行操作,现把实现总结如下:
打算分2篇总结:
第1篇总结Ftp的一些常规的操作实现(例如:上传,下载,新建,删除,FTP间互传文件等操作)
第2篇总结Ftp的操作的一些其他实现(例如:异步上传,异步下载等其他操作)

Microsoft .NET Framework 2.0新增加了3个类使我们很方便的对文件传输协议(FTP)服务器进行操作
FtpWebRequest类:实现文件传输协议(FTP)客户端
public sealed class FtpWebRequest : WebRequest

FtpWebResponse类:封装文件传输协议(FTP)服务器对请求的响应
public class FtpWebResponse : WebResponse, IDisposable

WebRequestMethods.Ftp类:表示可与FTP请求一起使用的FTP协议方法的类型,无法继承此类
public static class Ftp

类关系图
class

操作ftp的一般步骤我总结如下
第一步:WebRequest.Create方法,获得FtpWebRequest的实例
第二步:利用WebRequestMethods.Ftp设置FtpWebRequest的Method属性,指定使用的FTP协议方法的类型
第三步:设置FtpWebRequest的Credentials属性,指定用户名和密码
第四步:发出请求
第五步:接收响应数据流(有些ftp操作可能没这一步,例如给文件夹改名)
第六步:关闭流

下面从几段代码来分别展示ftp的不同操作:
1.文件夹和文件信息
关键知识说明:
a.FtpWebRequest类没有公开的构造函数,我们通过WebRequest.Create方法,获得FtpWebRequest的实例
b.通过WebRequestMethods.Ftp.ListDirectoryDetails(详细列表)或者WebRequestMethods.Ftp.ListDirectory(简短列表)获取FTP服务器上的文件列表
c.请求返回的数据在GetResponseStream方法返回的流中
d.字符编码请用System.Text.Encoding.Default,要不中文名会乱码
e.FtpWebRequest.Credentials属性设置登陆用户名和密码
f.FtpWebRequest.UseBinary属性,true,指示服务器要传输的是二进制数据.false,指示数据为文本。默认值为true
g.FtpWebRequest.EnableSsl属性,如果控制和数据传输是加密的,则为true.否则为false.默认值为 false

实例代码:
获取ftp://218.16.229.120上的文件信息
Uri uri = new Uri ( "ftp://218.16.229.120" );

FtpWebRequest listRequest = ( FtpWebRequest ) WebRequest.Create ( uri );

listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
//listRequest.Method = WebRequestMethods.Ftp.ListDirectory;

string ftpUser = "";
string ftpPassWord = "";
listRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

FtpWebResponse listResponse = ( FtpWebResponse ) listRequest.GetResponse ( );
Stream responseStream = listResponse.GetResponseStream ( );
StreamReader readStream = new StreamReader ( responseStream , System.Text.Encoding.Default );

if ( readStream != null )
{
    MessageBox.Show ( readStream.ReadToEnd ( )  );
}

MessageBox.Show ( string.Format ( "状态: {0},{1}" ,listResponse.StatusCode,  listResponse.StatusDescription ) );

listResponse.Close ( );
responseStream.Close ( );
readStream.Close ( );

通过WebRequestMethods.Ftp.ListDirectoryDetails(详细列表)或者WebRequestMethods.Ftp.ListDirectory(简短列表)返回的结果是不一样的.请看图
msg

利用WebRequestMethods.Ftp.ListDirectoryDetails,readStream.ReadToEnd ( )返回的字符串比较复杂(不同类型的Ftp会有不同返回形式的返回结果),要把里面的文件夹和文件区分列出来比较繁琐,代码比较多,所以我没写出来,感兴 趣的朋友可以留言,我可以邮件发送.

2.取ftp登陆身份验证完成后的欢迎信息
关键知识说明:
a.FtpWebResponse.WelcomeMessage属性获取身份验证完成时FTP服务器发送的消息

实例代码:
获取ftp://218.16.229.120登陆身份验证完成后的欢迎信息
Uri uri = new Uri ( "ftp://218.16.229.120" );

FtpWebRequest listRequest = ( FtpWebRequest ) WebRequest.Create ( uri );

listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

string ftpUser = "";
string ftpPassWord = "";
listRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

FtpWebResponse listResponse = ( FtpWebResponse ) listRequest.GetResponse ( );

MessageBox.Show ( listResponse.WelcomeMessage );

附加说明:要是FTP服务器的欢迎信息带有中文,运行这段代码时可能会发生异常(基础连接已经关闭: 服务器提交了协议).
解决办法:打补丁Microsoft .NET Framework 2.0 Service Pack 1

3.重命名目录
关键知识说明:
a.WebRequestMethods.Ftp.Rename表示重命名目录的FTP协议方法
b.FtpWebRequest.RenameTo属性重命名的新名称

实例代码:
把ftp://218.16.229.120/上的a目录重命名为av
Uri uri = new Uri ( "ftp://218.16.229.120/a" );

FtpWebRequest listRequest = ( FtpWebRequest ) WebRequest.Create ( uri );

listRequest.Method = WebRequestMethods.Ftp.Rename;

string ftpUser = "";
string ftpPassWord = "";
listRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

listRequest.RenameTo = "av";

FtpWebResponse listResponse = ( FtpWebResponse ) listRequest.GetResponse ( );

MessageBox.Show ( listResponse.StatusDescription );

4.删除目录
关键知识说明:
a.WebRequestMethods.Ftp.RemoveDirectory表示移除目录的FTP协议方法

实例代码:
删除ftp://218.16.229.120上的av文件夹
Uri uri = new Uri ( "ftp://218.16.229.120/av" );

FtpWebRequest listRequest = ( FtpWebRequest ) WebRequest.Create ( uri );

listRequest.Method = WebRequestMethods.Ftp.RemoveDirectory;

string ftpUser = "";
string ftpPassWord = "";
listRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

FtpWebResponse listResponse = ( FtpWebResponse ) listRequest.GetResponse ( );    

MessageBox.Show ( listResponse.StatusDescription );

5.新建目录
关键知识说明:
a.WebRequestMethods.Ftp.MakeDirectory表示在FTP服务器上创建目录的协议方法

实例代码:
在ftp://218.16.229.120上建立目录vb
Uri uri = new Uri ( "ftp://218.16.229.120/vb" );

FtpWebRequest listRequest = ( FtpWebRequest ) WebRequest.Create ( uri );

listRequest.Method = WebRequestMethods.Ftp.MakeDirectory;

string ftpUser = "";
string ftpPassWord = "";
listRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

FtpWebResponse listResponse = ( FtpWebResponse ) listRequest.GetResponse ( );

MessageBox.Show ( listResponse.StatusDescription );

6.得文件大小
关键知识说明:
a.WebRequestMethods.Ftp.GetFileSize表示要用于检索FTP服务器上的文件大小
b.流数据的长度可以从FtpWebResponse.ContentLength属性中获取。

实例代码:
获取ftp://218.16.229.120上的会议记录.doc文件大小
Uri uri = new Uri ( "ftp://218.16.229.120/会议记录.doc" );

FtpWebRequest listRequest = ( FtpWebRequest ) WebRequest.Create ( uri );

listRequest.Method = WebRequestMethods.Ftp.GetFileSize;

string ftpUser = "";
string ftpPassWord = "";
listRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

FtpWebResponse listResponse = ( FtpWebResponse ) listRequest.GetResponse ( );

MessageBox.Show ( string.Format ( "文件大小: {0}" , listResponse.ContentLength ) );

7.删除文件
关键知识说明:
a.WebRequestMethods.Ftp.DeleteFile表示要用于删除FTP服务器上的文件

实例代码:
删除ftp://218.16.229.120上的工作安排.txt文件
Uri uri = new Uri ( "ftp://218.16.229.120/工作安排.txt" );

FtpWebRequest listRequest = ( FtpWebRequest ) WebRequest.Create ( uri );

listRequest.Method = WebRequestMethods.Ftp.DeleteFile;

string ftpUser = "";
string ftpPassWord = "";
listRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

FtpWebResponse listResponse = ( FtpWebResponse ) listRequest.GetResponse ( );

MessageBox.Show ( string.Format ( "Delete status: {0}" , listResponse.StatusDescription ) );

8.上传文件
关键知识说明:
a.WebRequestMethods.Ftp.UploadFile表示将文件上载到FTP服务器
b.使用FtpWebRequest对象向服务器上载文件,则必须将文件内容写入请求流,请求流是通过调用FtpWebRequest.GetRequestStream方法.如果未将属性设置为UploadFile,则不能获取流。
c.异步对应方法(FtpWebRequest.BeginGetRequestStream方法和FtpWebRequest.EndGetRequestStream 方法),关于异步上传的实现我会再写在下篇总汇中

实例代码:
上载文件D:"abc.txt到ftp://218.16.229.120上
Stream requestStream = null;
FileStream fileStream = null;
FtpWebResponse uploadResponse = null;

try
{
    Uri uri = new Uri ( "ftp://218.16.229.120/abc.txt" );

    FtpWebRequest uploadRequest = ( FtpWebRequest ) WebRequest.Create ( uri );
    uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;

    string ftpUser = "";
    string ftpPassWord = "";
    uploadRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

    requestStream = uploadRequest.GetRequestStream ( );
    fileStream = File.Open ( @"D:"abc.txt" , FileMode.Open );

    byte [ ] buffer = new byte [ 1024 ];
    int bytesRead;
    while ( true )
    {
        bytesRead = fileStream.Read ( buffer , 0 , buffer.Length );
        if ( bytesRead == 0 )
            break;
        requestStream.Write ( buffer , 0 , bytesRead );
    }

    requestStream.Close ( );

    uploadResponse = ( FtpWebResponse ) uploadRequest.GetResponse ( );

    MessageBox.Show ( "Upload complete." );
}
finally
{
    if ( uploadResponse != null )
        uploadResponse.Close ( );
    if ( fileStream != null )
        fileStream.Close ( );
    if ( requestStream != null )
        requestStream.Close ( );
}


其实利用WebClient.UploadData方法,还有一种更简单的上传方法:
WebClient request = new WebClient ( );

string ftpUser = "";
string ftpPassWord = "";
request.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

FileStream myStream = new FileStream ( @"D:"abcd.txt" , FileMode.Open , FileAccess.Read );
byte [ ] dataByte = new byte [ myStream.Length ];
myStream.Read ( dataByte , 0 , dataByte.Length );  //写到2进制数组中
myStream.Close ( );

request.UploadData ( "ftp://218.16.229.120/abcd.txt" , dataByte );

9.下载文件
关键知识说明:
a.WebRequestMethods.Ftp.DownloadFile表示要用于从FTP服务器下载文件
b.从FTP服务器下载文件时,如果命令成功,所请求的文件的内容即在响应对象的流中。通过调用FtpWebResponse.GetResponseStream方法,可以访问此流。

实例代码:
从ftp://218.16.229.120上下载文件保存到d:"abc.txt
Stream responseStream = null;
FileStream fileStream = null;
StreamReader reader = null;

try
{
    string downloadUrl = "ftp://218.16.229.120/abc.txt";

    FtpWebRequest downloadRequest = ( FtpWebRequest ) WebRequest.Create ( downloadUrl );
    downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;

    string ftpUser = "";
    string ftpPassWord = "";
    downloadRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

    FtpWebResponse downloadResponse = ( FtpWebResponse ) downloadRequest.GetResponse ( );
    responseStream = downloadResponse.GetResponseStream ( );

    fileStream = File.Create ( @"d:"" + "abc.txt" );
    byte [ ] buffer = new byte [ 1024 ];
    int bytesRead;
    while ( true )
    {
        bytesRead = responseStream.Read ( buffer , 0 , buffer.Length );
        if ( bytesRead == 0 )
            break;
        fileStream.Write ( buffer , 0 , bytesRead );
    }
   
    MessageBox.Show ( "Download complete" );
}
finally
{
    if ( reader != null )
    {
        reader.Close ( );
    }
    else
    {
        if ( responseStream != null )
        {
            responseStream.Close ( );
        }
        if ( fileStream != null )
        {
            fileStream.Close ( );
        }
    }
}


其实利用WebClient.DownloadData方法,还有一种更简单的下载方法:
Uri uri = new Uri ( "ftp://218.16.229.120/abc.txt" );

WebClient request = new WebClient ( );

string ftpUser = "";
string ftpPassWord = "";
request.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

byte [ ] newFileData = request.DownloadData ( uri.ToString ( ) );

FileStream fs = new FileStream ( @"d:"abc.txt" , FileMode.OpenOrCreate , FileAccess.Write );
fs.Write ( newFileData , 0 , newFileData.Length );
fs.Close ( );

10.2个ftp间传送文件
关键知识说明:
a.在搞懂前面所说下载和上传知识后,其实很好实现2个ftp间传送文件.我们可以把传送文件看成是先下载后上传.把下载的文件响应流数据写到上传文件请求流中即可.

实例代码:
把ftp://218.58.58.19中"集团公司通知"目录中的"080124-成本费用科目调整通知.pdf"文件传送到ftp://218.16.229.120
string downloadUrl = "ftp://218.58.58.19/集团公司通知/080124-成本费用科目调整通知.pdf";
FtpWebRequest downloadRequest = ( FtpWebRequest ) WebRequest.Create ( downloadUrl );
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;

string ftpUser = "download";
string ftpPassWord = "download";
downloadRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );

string uploadUrl = "ftp://218.16.229.120/080124-成本费用科目调整通知.pdf";
FtpWebRequest uploadRequest = ( FtpWebRequest ) WebRequest.Create ( uploadUrl );
uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;

string ftpUser1 = "exwangsoft";
string ftpPassWord1 = "exwangsoft";
uploadRequest.Credentials = new NetworkCredential ( ftpUser1 , ftpPassWord1 );

FtpWebResponse downloadResponse = ( FtpWebResponse ) downloadRequest.GetResponse ( );
Stream responseStream = downloadResponse.GetResponseStream ( );

Stream fileStream = uploadRequest.GetRequestStream ( );
byte [ ] buffer = new byte [ 1024 ];
int bytesRead;
while ( true )
{
    //读取ftp://218.58.58.19的响应流数据
    bytesRead = responseStream.Read ( buffer , 0 , buffer.Length );
    if ( bytesRead == 0 )
        break;
    //写到ftp://218.16.229.120的请求流数据中
    fileStream.Write ( buffer , 0 , bytesRead );
}

fileStream.Close ( );
FtpWebResponse uploadResponse = null;
uploadResponse = ( FtpWebResponse ) uploadRequest.GetResponse ( );

MessageBox.Show ( "complete" );