首页 > 代码库 > C#的FTP上传下载的实验

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("/") + 1));                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[1024];                int bytesRead;                while (true)                {                    bytesRead = fileStream.Read(buffer, 0, buffer.Length);                    if (bytesRead == 0)                        break;                    upLoadStream.Write(buffer, 0, 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(" ") + 1));                else                    files.Add(line.Substring(line.LastIndexOf(" ") + 1));                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(获取子文件夹信息)、RenameMakeDirectory(创建文件夹)、UploadFileListDirectoryDetails(获取子文件夹及文件信息)、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服务以及如何调试(这个有时间、有闲心的话,也写一下,贡以后自己参考吧)。

C#的FTP上传下载的实验