C#的FTP上传下载的实验

时间:2023-03-09 19:27:24
C#的FTP上传下载的实验

前段时间做了一个FTP操作服务器文件的实验,现在把一些经验写下来,免得忘记。

1、上传的处理:目标文件夹A上传到服务器指定目录。先检索服务器目录中有无同名文件夹,若有,则先改名,上传成功后再删除,上传失败则回复文件夹名。

1)、检查文件夹是否存在

        /// <summary>
/// 检查文件夹在服务器上是否已存在
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private static bool CheckExist(string fileName)
{
FtpWebRequest checkRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(_upLoadPath));
checkRequest.Method = WebRequestMethods.Ftp.ListDirectory;
checkRequest.UseBinary = true;
checkRequest.Credentials = new NetworkCredential(_userName, _password);
FtpWebResponse response = (FtpWebResponse)checkRequest.GetResponse();
StreamReader sw = new StreamReader(response.GetResponseStream()); List<string> files = new List<string>();
string line = sw.ReadLine();
while (line != null)
{
files.Add(line.Substring(line.IndexOf("/") + ));
line = sw.ReadLine();
} sw.Close();
response.Close();
return files.Contains(fileName);
}

2)、文件夹的重命名

        /// <summary>
/// 文件夹重命名
/// </summary>
/// <param name="oldName"></param>
/// <param name="newName"></param>
private static void RenameFolder(string oldName, string newName)
{
string uri = _upLoadPath + "/" + oldName;
FtpWebRequest ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
ftpRequest.Method = WebRequestMethods.Ftp.Rename;
ftpRequest.UseBinary = true;
ftpRequest.Credentials = new NetworkCredential(_userName, _password);
ftpRequest.RenameTo = newName;
FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
}

3)、文件夹的上传

        /// <summary>
/// 上传文件夹
/// </summary>
/// <param name="folderInfo">待上传文件夹的信息</param>
private static void UpLoadFolder(DirectoryInfo folderInfo)
{
// 服务器上文件夹的位置为根目录加上相对位置
// rootPath = (new DirectoryInfo(_localPath)).Parent.FullName; rootPath是待上传文件夹的目录
string foldePath = folderInfo.FullName.Substring(rootPath.Length).Replace('\\', '/');
string uriPath = _upLoadPath + "/" + foldePath;
// 创建文件夹
CreateFolder(uriPath);
// 递归创建子文件夹并上传文件
if (folderInfo != null)
{
foreach (DirectoryInfo folder in folderInfo.GetDirectories())
{
UpLoadFolder(folder);
}
foreach (FileInfo file in folderInfo.GetFiles())
{
UpLoadFile(file);
}
}
}
        /// <summary>
/// 创建文件夹
/// </summary>
/// <param name="folderPath">文件夹路径</param>
private static void CreateFolder(string folderPath)
{
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uriPath));
request.Method = WebRequestMethods.Ftp.MakeDirectory;
request.UseBinary = true;
request.Credentials = new NetworkCredential(_userName, _password);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream ftpStream = response.GetResponseStream();
ftpStream.Close();
response.Close();
}
        /// <summary>
/// 上传单个文件
/// </summary>
/// <param name="file"></param>
private static void UpLoadFile(FileInfo file)
{
// 服务器上文件的位置为根目录加上相对位置
string fileName = file.FullName.Substring(rootPath.Length).Replace('\\', '/');
string uriPath = _upLoadPath + "/" + fileName;
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uriPath));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(_userName, _password); FtpWebResponse upLoadResponse = (FtpWebResponse)request.GetResponse();
Stream upLoadStream = request.GetRequestStream(); using (FileStream fileStream = File.Open(file.FullName, FileMode.Open))
{ byte[] buffer = new byte[];
int bytesRead;
while (true)
{
bytesRead = fileStream.Read(buffer, , buffer.Length);
if (bytesRead == )
break;
upLoadStream.Write(buffer, , bytesRead);
}
}
upLoadStream.Close();
upLoadResponse.Close();
}

4)、文件夹的删除

        /// <summary>
/// 删除文件夹及子文件和子文件夹
/// </summary>
/// <param name="folderName"></param>
private static void DeleteFolder(string folderName)
{
string uri = _upLoadPath + "/" + folderName;
FtpWebRequest searchRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
searchRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
searchRequest.Credentials = new NetworkCredential(_userName, _password);
FtpWebResponse searchResponse = (FtpWebResponse)searchRequest.GetResponse();
StreamReader sw = new StreamReader(searchResponse.GetResponseStream()); List<string> files = new List<string>();
List<string> folders = new List<string>();
string line = sw.ReadLine();
while (line != null)
{
// windows下的文件夹读取到的数据以“d”开头,以“空格” + 文件夹名 结束
if (line.StartsWith("d"))
folders.Add(line.Substring(line.LastIndexOf(" ") + ));
else
files.Add(line.Substring(line.LastIndexOf(" ") + ));
line = sw.ReadLine();
}
sw.Close();
searchResponse.Close(); // 递归删除服务器上的文件夹和文件
foreach (string folder in folders)
{
DeleteFolder(folderName + "/" + folder);
}
foreach (string file in files)
{
DeleteFile(folderName + "/" + file);
} FtpWebRequest deleteRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
deleteRequest.Method = WebRequestMethods.Ftp.RemoveDirectory;
deleteRequest.Credentials = new NetworkCredential(_userName, _password);
FtpWebResponse deleteResponse = (FtpWebResponse)deleteRequest.GetResponse();
deleteResponse.Close();
}
        /// <summary>
/// 删除单个文件
/// </summary>
/// <param name="fileName"></param>
private static void DeleteFile(string fileName)
{
string uri = _upLoadPath + "/" + fileName;
FtpWebRequest deleteRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
deleteRequest.Method = WebRequestMethods.Ftp.DeleteFile;
deleteRequest.Credentials = new NetworkCredential(_userName, _password);
FtpWebResponse deleteResponse = (FtpWebResponse)deleteRequest.GetResponse();
deleteResponse.Close();
}

至此,上传算是完成了。一些异常处理,配置文件的格式就不贴出来了。

2)、下载,一样是重命名,下载,删除的套路。但重命名和删除是在本地,很容易实现。而FTP下载的代码也与上传代码非常镜像,递归创建子文件夹和读取写文件就好了。

总结:对于ftp服务器上文件的任何操作

1.都需要用Uri(包含IP、端口号和目录的完整路径)去实例化一个FtpWebRequest对象。

2.用FtpWebRequest对象的Method属性来选择操作文件的方式,本文出现了ListDirectory(获取子文件夹信息)、Rename、MakeDirectory(创建文件夹)、UploadFile、ListDirectoryDetails(获取子文件夹及文件信息)、RemoveDirectory、DeleteFile以及文中没有出现但下载需用到的DownloadFile。

3.连接FTP服务器XXXXRequest.Credentials = new NetworkCredential(_userName, _password)

4.得到FTP的响应对象FtpWebResponse

5.如有必要,可获得响应对象FtpWebResponse的流GetRequestStream(),并进行读写操作。

可以看到FTP各种操作的相关代码非常类似,容易看懂,功能清晰。通过这次实验,接触了FTP服务器的搭建(FileZilla Server Interface工具一路点下一步。。。),学习了C#怎么实现FTP的上传下载,怎么用C#写windows服务以及如何调试(这个有时间、有闲心的话,也写一下,贡以后自己参考吧)。