近期做ftp通信时,发现网上都是只能从ftp下载文件而不能直接下载整个文件夹,大家都知道要递归,但我没找到直接可以用的代码,所以自己花时间写了一个可以直接用的,已测试通过。值得注意的时,我通信的ftp服务器中,目录的标识不是网上大多数的<DIR>标识,而是文件信息字符串是"drwxr-xr-x ... ...fileName",在这里我两个都写了一下。如果你们的跟我不同,请自行调整。
帮助类直接奉上
public class FtpHelper
{
/// <summary>
/// 初始ftp路径
/// </summary>
public static string initFtpPath = "ftp://root:123@192.168.1.21/lts/note/";
/// <summary>
/// 本地保存根路径
/// </summary>
public static string hardwareDataSavePath = Environment.CurrentDirectory + "/Data/RemoteData/";//
/// <summary>
/// 单个文件下载方法
/// </summary>
/// <param name="localPath">保存文件的本地路径</param>
/// <param name="ftpPath">下载文件的FTP路径</param>
public void Download(string ftpPath, string localSavePath)
{
try
{
//FileMode常数确定如何打开或创建文件,指定操作系统应创建新文件。
//FileMode.Create如果文件已存在,它将被改写
FileStream outputStream = new FileStream(localSavePath, FileMode.Create);
FtpWebRequest downRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpPath));
//设置要发送到 FTP 服务器的命令
downRequest.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = (FtpWebResponse)downRequest.GetResponse();
Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
outputStream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
ftpStream.Close();
outputStream.Close();
response.Close();
}
catch (Exception ee)
{
Console.WriteLine("Download方法异常:"+ee.ToString());
}
}
/// <summary>
/// 获取ftp的文件列表
/// </summary>
/// <param name="ftpPath">FTP地址路径</param>
/// <param name="fileName">我们所选择的文件或者文件夹名字</param>
/// <param name="type">要发送到FTP服务器的命令(WebRequestMethods.Ftp.ListDirectoryDetails或WebRequestMethods.Ftp.ListDirectory)</param>
/// <returns></returns>
public string[] GetFtpList(string ftpPath, string fileName, string type)
{
string[] fen = null;
try
{
WebResponse webresp = null;
StreamReader ftpFileListReader = null;
FtpWebRequest ftpRequest = null;
ftpRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpPath + fileName));
ftpRequest.Method = type;
webresp = ftpRequest.GetResponse();
ftpFileListReader = new StreamReader(webresp.GetResponseStream(), Encoding.Default);
StringBuilder str = new StringBuilder();
string line = ftpFileListReader.ReadLine();
while (line != null)
{
if (line.Trim() == "")
{
continue;
}
str.Append(line);
str.Append("\n");
line = ftpFileListReader.ReadLine();
}
if (str != null && str.Length > 0)
{
str.Remove(str.Length - 1, 1);
}
fen = str.ToString().Split('\n');
}
catch (Exception ex)
{
fen = null;
Console.WriteLine(ex.ToString());
}
return fen;
}
/// <summary>
/// 整个文件夹的文件及子目录 下载方法
/// </summary>
/// <param name="ftpPath">FTP路径</param>
/// <param name="localSavePath">保存的本地路径</param>
public void DownFtp(string ftpPath, string localSavePath)
{
try
{
string downloadDir = localSavePath;
string ftpdir = ftpPath;
string[] fullname = GetFtpList(ftpdir, "", WebRequestMethods.Ftp.ListDirectoryDetails);
string[] onlyname = GetFtpList(ftpdir, "", WebRequestMethods.Ftp.ListDirectory);
if (!Directory.Exists(downloadDir))
{
Directory.CreateDirectory(downloadDir);
}
if (fullname == null || fullname.Length == 0)
{
return;
}
foreach (string names in fullname)
{
if (names.Trim() == "")
{
continue;
}
//判断是否具有文件夹标识<DIR>或者names的首字符是d (两者均表示此路径是文件夹而非文件)
if (names.Contains("<DIR>") || names[0].ToString() == "d")
{
if (names.Contains("<DIR>"))
{
string olname = names.Split(new string[] { "<DIR>" },StringSplitOptions.None)[1].Trim();
DownFtp(ftpdir + olname + "/", downloadDir + olname + "/");
}
else if (names[0].ToString() == "d")
{
string[] strDirInfo = System.Text.RegularExpressions.Regex.Split(names, @"\s+");
DownFtp(ftpdir + strDirInfo[strDirInfo.Length - 1] + "/", downloadDir + strDirInfo[strDirInfo.Length - 1] + "/");
}
}
else
{
foreach (string onlynames in onlyname)
{
if (onlynames.Trim() == "")
{
continue;
}
else
{
if (names.Contains(" " + onlynames))
{
string fileFullName = ftpdir + onlynames;
//在本地查找是否已存在此文件,若已存在,则不再下载
if (File.Exists(fileFullName.Replace(initFtpPath, hardwareDataSavePath)))
{
Console.WriteLine(onlynames);
break;
}
Console.WriteLine("下载" + onlynames);
Download(fileFullName, downloadDir + onlynames);
break;
}
}
}
}
}
}
catch (Exception ee)
{
Console.WriteLine("异常信息:" + ee.ToString());
}
}
/// 清空指定的文件夹(包括子目录文件夹),但不删除文件夹
/// </summary>
/// <param name="dir">指定目录</param>
public static void DeleteFolder(string dir)
{
foreach (string d in Directory.GetFileSystemEntries(dir))
{
if (System.IO.File.Exists(d))
{
FileInfo fi = new FileInfo(d);
if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
fi.Attributes = FileAttributes.Normal;
System.IO.File.Delete(d);//直接删除其中的文件
}
else
{
DirectoryInfo d1 = new DirectoryInfo(d);
if (d1.GetFiles().Length != 0 || d1.GetDirectories().Length != 0)
{
DeleteFolder(d1.FullName);递归删除子文件夹
}
Directory.Delete(d);
}
}
}
}
调用示例
FtpHelper ftphelper = new FtpHelper();
//从硬件的ftp服务器同步数据到本地
ftphelper.DownFtp(FtpHelper.initFtpPath, FtpHelper.hardwareDataSavePath);
谢谢观看,好用的话记得点赞和评论哟O(∩_∩)O哈哈~