.net 中FTP下载文件问题 顶者有分!

IMAGSE 2010-10-20 11:51:42
下面是.NET中提供的WebRequestMethods.Ftp下可用的方法
但是现在我遇到问题是我需要连接一台Linux SUSE主机,目录中有几万个文件,常用的FlashFxp,CuteFTP,LeapFTp等等,都是只能显示1999个文件,同中兴工程师确认过,其他厂家也有此情况存在,也就是FTP中的ls不能列出完整列表,用mget强行下载,用通配符匹配的文件可以实现,我刚刚在cmd控制台中试过。
但是请问在.NET中怎样实现我cmd中用mget命令一样的功能呢?
用C#执行CMD命令启动FTP的话,其中密码必须输入,程序赋值不成功。
在网上也见有的网友这么做,但是不行
网友方法见连接:http://www.i-ok.net/CSharp/articles/9ku1ciah.htm
那么我该如何实现呢?
自己寫Socket發送FTP命令實現????
请各位给与指导,谢谢!
            // 摘要:
// 表示要用于将文件追加到 FTP 服务器上的现有文件的 FTP APPE 协议方法。
public const string AppendFile = "APPE";
//
// 摘要:
// 表示要用于删除 FTP 服务器上的文件的 FTP DELE 协议方法。
public const string DeleteFile = "DELE";
//
// 摘要:
// 表示要用于从 FTP 服务器下载文件的 FTP RETR 协议方法。
public const string DownloadFile = "RETR";
public const string GetDateTimestamp = "MDTM";
//
// 摘要:
// 表示要用于检索 FTP 服务器上的文件大小的 FTP SIZE 协议方法。
public const string GetFileSize = "SIZE";
//
// 摘要:
// 表示获取 FTP 服务器上的文件的简短列表的 FTP NLIST 协议方法。
public const string ListDirectory = "NLST";
//
// 摘要:
// 表示获取 FTP 服务器上的文件的详细列表的 FTP LIST 协议方法。
public const string ListDirectoryDetails = "LIST";
//
// 摘要:
// 表示在 FTP 服务器上创建目录的 FTP MKD 协议方法。
public const string MakeDirectory = "MKD";
//
// 摘要:
// 表示打印当前工作目录的名称的 FTP PWD 协议方法。
public const string PrintWorkingDirectory = "PWD";
//
// 摘要:
// 表示移除目录的 FTP RMD 协议方法。
public const string RemoveDirectory = "RMD";
//
// 摘要:
// 表示重命名目录的 FTP RENAME 协议方法。
public const string Rename = "RENAME";
//
// 摘要:
// 表示将文件上载到 FTP 服务器的 FTP STOR 协议方法。
public const string UploadFile = "STOR";
//
// 摘要:
// 表示将具有唯一名称的文件上载到 FTP 服务器的 FTP STOU 协议方法。
public const string UploadFileWithUniqueName = "STOU";
...全文
312 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
IMAGSE 2010-10-21
  • 打赏
  • 举报
回复
感谢各位朋友的帮助!
IMAGSE 2010-10-21
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 jshi123 的回复:]
你可以建一个ftp自动执行的批文件,比如ftpbatch.txt:
open xxx.xxx.xxx.xxx

user <user> xxxxx
lcd d:\test
mget *.*
bye

然后运行命令:ftp -s:ftpbatch.txt
就可以完成批文件下载

如果用c#编程实现的话,可能要用socket来写,比较麻烦,可以找一些现成的dll:
Chilka……
[/Quote]

感谢,就是这个东东,呵呵,我还是要用C#写的,因为下载完还要将这些文件进行读写处理后保存在上传到其他服务器!
剩下的就好说了。非常感谢!
jshi123 2010-10-21
  • 打赏
  • 举报
回复
你可以建一个ftp自动执行的批文件,比如ftpbatch.txt:
open xxx.xxx.xxx.xxx

user <user> xxxxx
lcd d:\test
mget *.*
bye

然后运行命令:ftp -s:ftpbatch.txt
就可以完成批文件下载

如果用c#编程实现的话,可能要用socket来写,比较麻烦,可以找一些现成的dll:
Chilkat .NET
PowerTCP FTP(评估版)
这两个都是支持mget的。

另外你可以试下:ls UN20101020*
如果这个命令可以执行成功的话,就可以用FtpWebRequest循环下载文件就可以了。


kkbac 2010-10-20
  • 打赏
  • 举报
回复

同上。
z289830131 2010-10-20
  • 打赏
  • 举报
回复

先顶再看..
仙儿 2010-10-20
  • 打赏
  • 举报
回复
LZ 结贴给分了 貌似下班时间到了
想哥 2010-10-20
  • 打赏
  • 举报
回复
顶起。学习。
BossFriday 2010-10-20
  • 打赏
  • 举报
回复
百度一个ftphelper
hookyzlr 2010-10-20
  • 打赏
  • 举报
回复
代码没发完,需要的话留言,给你发到邮箱。
吴青峰 2010-10-20
  • 打赏
  • 举报
回复
凑下热闹。
sql_cctv 2010-10-20
  • 打赏
  • 举报
回复


我顶啊
LZ给分
仙儿 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 hookyzlr 的回复:]

C# code

/// <summary>
/// Return a detailed directory listing
/// </summary>
/// <param name="directory">Directory to list, e.g. /pub/etc</param>
/// <returns>An FTP……
[/Quote]


我顶啊
LZ给分
hookyzlr 2010-10-20
  • 打赏
  • 举报
回复

/// <summary>
/// Return a detailed directory listing
/// </summary>
/// <param name="directory">Directory to list, e.g. /pub/etc</param>
/// <returns>An FTPDirectory object</returns>
public FTPdirectory ListDirectoryDetail(string directory)
{
System.Net.FtpWebRequest ftp = GetRequest(GetDirectory(directory));
//Set request to do simple list
ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails;

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
return new FTPdirectory(str, _lastDirectory);
}

#endregion

#region "Upload: File transfer TO ftp server"
/// <summary>
/// Copy a local file to the FTP server
/// </summary>
/// <param name="localFilename">Full path of the local file</param>
/// <param name="targetFilename">Target filename, if required</param>
/// <returns></returns>
/// <remarks>If the target filename is blank, the source filename is used
/// (assumes current directory). Otherwise use a filename to specify a name
/// or a full path and filename if required.</remarks>
public bool Upload(string localFilename, string targetFilename)
{
//1. check source
if (!File.Exists(localFilename))
{
throw (new ApplicationException("File " + localFilename + " not found"));
}
//copy to FI
FileInfo fi = new FileInfo(localFilename);
return Upload(fi, targetFilename);
}

/// <summary>
/// Upload a local file to the FTP server
/// </summary>
/// <param name="fi">Source file</param>
/// <param name="targetFilename">Target filename (optional)</param>
/// <returns></returns>
public bool Upload(FileInfo fi, string targetFilename)
{
//copy the file specified to target file: target file can be full path or just filename (uses current dir)

//1. check target
string target;
if (targetFilename.Trim() == "")
{
//Blank target: use source filename & current dir
target = this.CurrentDirectory + fi.Name;
}
else if (targetFilename.Contains("/"))
{
//If contains / treat as a full path
target = AdjustDir(targetFilename);
}
else
{
//otherwise treat as filename only, use current directory
target = CurrentDirectory + targetFilename;
}

string URI = Hostname+":"+port + target;
//perform copy
System.Net.FtpWebRequest ftp = GetRequest(URI);

//Set request to upload a file in binary
ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
ftp.UseBinary = true;

//Notify FTP of the expected size
ftp.ContentLength = fi.Length;

//create byte array to store: ensure at least 1 byte!
const int BufferSize = 2048;
byte[] content = new byte[BufferSize - 1 + 1];
int dataRead;

//open file for reading
using (FileStream fs = fi.OpenRead())
{
try
{
//open request to send
using (Stream rs = ftp.GetRequestStream())
{
do
{
dataRead = fs.Read(content, 0, BufferSize);
rs.Write(content, 0, dataRead);
} while (!(dataRead < BufferSize));
rs.Close();
}
}
catch (Exception)
{

}
finally
{
//ensure file closed
fs.Close();
}

}


ftp = null;
return true;

}
#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</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);
}

//Version taking an FtpFileInfo
public bool Download(FTPfileInfo file, string localFilename, bool PermitOverwrite)
{
return this.Download(file.FullName, localFilename, PermitOverwrite);
}

//Another version taking FtpFileInfo and FileInfo
public bool Download(FTPfileInfo file, FileInfo localFI, bool PermitOverwrite)
{
return this.Download(file.FullName, localFI, PermitOverwrite);
}

//Version taking string/FileInfo
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
string target;
if (sourceFilename.Trim() == "")
{
throw (new ApplicationException("File not specified"));
}
else if (sourceFilename.Contains("/"))
{
//treat as a full path
target = AdjustDir(sourceFilename);
}
else
{
//treat as filename only, use current directory
target = CurrentDirectory + sourceFilename;
}

string URI = Hostname+":"+port + target;

//3. perform copy
System.Net.FtpWebRequest ftp = GetRequest(URI);

//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
using (FileStream fs = targetFI.OpenWrite())
{
try
{
byte[] buffer = new byte[2048];
int read = 0;
do
{
read = responseStream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, read);
} while (!(read == 0));
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 "Other functions: Delete rename etc."
/// <summary>
/// Delete remote file
/// </summary>
/// <param name="filename">filename or full path</param>
/// <returns></returns>
/// <remarks></remarks>
public bool FtpDelete(string filename)
{
//Determine if file or full path
string URI = this.Hostname+":"+port + GetFullPath(filename);

System.Net.FtpWebRequest ftp = GetRequest(URI);
//Set request to delete
ftp.Method = System.Net.WebRequestMethods.Ftp.DeleteFile;
try
{
//get response but ignore it
string str = GetStringResponse(ftp);
}
catch (Exception)
{
return false;
}
return true;
}
hookyzlr 2010-10-20
  • 打赏
  • 举报
回复

/// <summary>
/// 关闭所有链接
/// </summary>
public void Disconnect()
{
CloseDataSocket();

if (main_sock != null)
{
if (main_sock.Connected)
{
SendCommand("QUIT");
main_sock.Close();
}
main_sock = null;
}

if (file != null)
file.Close();

main_ipEndPoint = null;
file = null;
}

private void CloseDataSocket()
{
if (data_sock != null)
{
if (data_sock.Connected)
{
data_sock.Close();
}
data_sock = null;
}

data_ipEndPoint = null;
}

/// <summary>
/// 发送命令
/// </summary>
/// <param name="command"></param>
private void SendCommand(string command)
{
Byte[] cmd = Encoding.ASCII.GetBytes((command + "\r\n").ToCharArray());

if (command.Length > 3 && command.Substring(0, 4) == "PASS")
{
messages = "\rPASS xxx";
}
else
{
messages = "\r" + command;
}

try
{
main_sock.Send(cmd, cmd.Length, 0);
}
catch (Exception ex)
{
try
{
Disconnect();
errormessage += ex.Message;
return;
}
catch
{
main_sock.Close();
file.Close();
main_sock = null;
main_ipEndPoint = null;
file = null;
}
}
}

/// <summary>
/// 操作失败
/// </summary>
private void Fail()
{
Disconnect();
errormessage += responseStr;
//throw new Exception(responseStr);
}

/// <summary>
/// 返回服务器端返回信息
/// </summary>
private void ReadResponse()
{
string buf;
messages = "";

while (true)
{
buf = GetLineFromBucket();

if (Regex.Match(buf, "^[0-9]+ ").Success)
{
responseStr = buf;
response = int.Parse(buf.Substring(0, 3));
break;
}
else
messages += Regex.Replace(buf, "^[0-9]+-", "") + "\n";
}
}

private string GetLineFromBucket()
{
int i;
string buf = "";

if ((i = bucket.IndexOf('\n')) < 0)
{
while (i < 0)
{
FillBucket();
i = bucket.IndexOf('\n');
}
}

buf = bucket.Substring(0, i);
bucket = bucket.Substring(i + 1);

return buf;
}

private void FillBucket()
{
Byte[] bytes = new Byte[512];
long bytesgot;
int msecs_passed = 0;

while (main_sock.Available < 1)
{
System.Threading.Thread.Sleep(50);
msecs_passed += 50;
//当等待时间到,则断开链接
if (msecs_passed > timeout)
{
Disconnect();
errormessage += "Timed out waiting on server to respond.";
return;
}
}

while (main_sock.Available > 0)
{
bytesgot = main_sock.Receive(bytes, 512, 0);
bucket += Encoding.ASCII.GetString(bytes, 0, (int)bytesgot);
System.Threading.Thread.Sleep(50);
}
}

/// <summary>
/// Constructor taking hostname, username and password
/// </summary>
/// <param name="Hostname">in either ftp://ftp.host.com or ftp.host.com form</param>
/// <param name="Username">Leave blank to use 'anonymous' but set password to your email</param>
/// <param name="Password"></param>
/// <remarks></remarks>
public FTPclient(string Hostname, string Username, string Password)
{
_hostname = Hostname;
_username = Username;
_password = Password;
}
#endregion

#region "Directory functions"
/// <summary>
/// Return a simple directory listing
/// </summary>
/// <param name="directory">Directory to list, e.g. /pub</param>
/// <returns>A list of filenames and directories as a List(of String)</returns>
/// <remarks>For a detailed directory listing, use ListDirectoryDetail</remarks>
public List<string> ListDirectory(string directory)
{
try
{
Uri uri = new Uri(Hostname+":"+port + directory);

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

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

listRequest.Credentials = new NetworkCredential(_username, _password);

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

string str = readStream.ReadToEnd();
List<string> result = new List<string>();
result.AddRange(str.Split('\r'));

listResponse.Close();
responseStream.Close();
readStream.Close();
return result;
}
catch (Exception err)
{
return null;
}


/* //return a simple list of filenames in directory
System.Net.FtpWebRequest ftp = GetRequest(GetDirectory(directory));
//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;*/
}
hookyzlr 2010-10-20
  • 打赏
  • 举报
回复
原来做过FTP上传,不过用的是别人开发的一个类,还可以。

using System.Diagnostics;
using System.Data;
using System.Collections;
using Microsoft.VisualBasic;
using System.Collections.Generic;
using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text.RegularExpressions;
using System.Text;

namespace AlumnusManage
{
#region "FTP client class"
/// <summary>
/// A wrapper class for .NET 2.0 FTP
/// </summary>
/// <remarks>
/// This class does not hold open an FTP connection but
/// instead is stateless: for each FTP request it
/// connects, performs the request and disconnects.
/// </remarks>
public class FTPclient
{
/// <summary>
/// 端口号
/// </summary>
public int port;

/// <summary>
/// 无响应时间(FTP在指定时间内无响应)
/// </summary>
public int timeout=1000;

/// <summary>
/// 主套接字
/// </summary>
private Socket main_sock;

/// <summary>
/// 数据套接字
/// </summary>
private Socket data_sock;

/// <summary>
/// 要链接的网络地址终结点
/// </summary>
private IPEndPoint main_ipEndPoint;

/// <summary>
/// 与FTP服务器交互的状态值
/// </summary>
private int response;

/// <summary>
/// 服务器错误状态信息
/// </summary>
public string errormessage="";

/// <summary>
/// 服务器的响应信息
/// </summary>
private string responseStr;

/// <summary>
/// 要链接的网络数据地址终结点
/// </summary>
private IPEndPoint data_ipEndPoint;

/// <summary>
/// 服务器状态返回信息
/// </summary>
private string messages="";

/// <summary>
/// 读取并保存当前命令执行后从FTP服务器端返回的数据信息
/// </summary>
private string bucket="";

/// <summary>
/// 用于上传或下载的文件流对象
/// </summary>
private FileStream file;

#region "CONSTRUCTORS"
/// <summary>
/// Blank constructor
/// </summary>
/// <remarks>Hostname, username and password must be set manually</remarks>
public FTPclient()
{
}

/// <summary>
/// Constructor just taking the hostname
/// </summary>
/// <param name="Hostname">in either ftp://ftp.host.com or ftp.host.com form</param>
/// <remarks></remarks>
public FTPclient(string Hostname)
{
_hostname = Hostname;
}

/// <summary>
/// 链接到FTP服务器
/// </summary>
/// <param name="server">要链接的IP地址或主机名</param>
/// <param name="user">登陆帐号</param>
/// <param name="pass">登陆口令</param>
public bool Connect(string server, string user, string pass)
{
this._hostname = server;
this._username = user;
this._password = pass;

return Connect();
}

/// <summary>
/// 链接到FTP服务器
/// </summary>
public bool Connect()
{
if (_hostname == null)
{
errormessage += "No server has been set.\r\n";
}
if (_username == null)
{
errormessage += "No server has been set.\r\n";
}

if (main_sock != null)
if (main_sock.Connected)
return true;

try
{
main_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
#if NET1
main_ipEndPoint = new IPEndPoint(System.Net.Dns.GetHostEntry(server).AddressList[0], port);
#else
main_ipEndPoint = new IPEndPoint(Dns.GetHostByName(_hostname).AddressList[0], port);
#endif

main_sock.Connect(main_ipEndPoint);
}
catch (Exception ex)
{
errormessage += ex.Message;
return false;
}

ReadResponse();
if (response != 220)
Fail();

SendCommand("USER " + _username);
ReadResponse();

switch (response)
{
case 331:
if (_password == null)
{
Disconnect();
errormessage += "No password has been set.";
return false;
}
SendCommand("PASS " + _password);
ReadResponse();
if (response != 230)
{
Fail();
return false;
}
break;
case 230:
break;
}

return true;
}
HooverHuang 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用楼主 imagse 的回复:]
下面是.NET中提供的WebRequestMethods.Ftp下可用的方法
但是现在我遇到问题是我需要连接一台Linux SUSE主机,目录中有几万个文件,常用的FlashFxp,CuteFTP,LeapFTp等等,都是只能显示1999个文件,同中兴工程师确认过,其他厂家也有此情况存在,也就是FTP中的ls不能列出完整列表,用mget强行下载,用通配符匹配的文件可以实现,我刚刚在cmd控制台中……
[/Quote]
嘿嘿,我以前也研究过这个问题,但后来那个项目公司没让我做,就夭折了。帮你顶下
ton2006 2010-10-20
  • 打赏
  • 举报
回复
顶。。。。。。。
porschev 2010-10-20
  • 打赏
  • 举报
回复
up....不会。。
MSDNXGH 2010-10-20
  • 打赏
  • 举报
回复
顶。。。。。。。
IMAGSE 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 wuyq11 的回复:]

http://www.codeproject.com/KB/IP/SimpleFTPDemo.aspx
[/Quote]
谢谢!
这个方法我在用,但是WebRequestMethods.Ftp.DownloadFile对应的FTP命令是RETR,我试过这个命令是不能想mget一样。
可以这样的:FTP>mget UN20101020*这种通配符的方式。
加载更多回复(1)

62,040

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧