FTP文件操作

1. 前提步骤:完成相应的FTP设置

2. 说明

   命名空间:

   using System.NET;     using System.IO;    

   实现过程:

     1、创建一个FTP WebRequest对象,指向FTP服务器的uri

     2、设置FTP的执行方法(上传,下载等)

     3、给FTP WebRequest对象设置属性(是否支持ssl,是否使用二进制传输等)

     4、设置登录验证(用户名,密码)

     5、执行请求

     6、接收相应流(如果需要的话)

     7、如果没有打开的流,则关闭FTP请求

     FTP WebRequest对象的属性

     ◆Credentials - 指定登录FTP服务器的用户名和密码。

     ◆KeepAlive - 指定连接是应该关闭还是在请求完成之后关闭,默认为true

     ◆UseBinary - 指定文件传输的类型。有两种文件传输模式,一种是Binary,另一种是ASCII。两种方法在传输时,字节的第8位是不同的。ASCII使用第8位作为错误控制,而Binary的8位都是有意义的。所以当你使用ASCII传输时要小心一些。简单的说,如果能用记事本读和写的文件用ASCII传输就是安全的,而其他的则必须使用Binary模式。当然使用Binary模式发送ASCII文件也是非常好的。

     ◆UsePassive - 指定使用主动模式还是被动模式。早先所有客户端都使用主动模式,而且工作的很好,而现在因为客户端防火墙的存在,将会关闭一些端口,这样主动模式将会失败。在这种情况下就要使用被动模式,但是一些端口也可能被服务器的防火墙封掉。不过因为FTP服务器需要它的FTP服务连接到一定数量的客户端,所以他们总是支持被动模式的。这就是我们为什么要使用被动模式的原意,为了确保数据可以正确的传输,使用被动模式要明显优于主动模式。(译者注:主动(PORT)模式建立数据传输通道是由服务器端发起的,服务器使用20端口连接客户端的某一个大于1024的端口;在被动(PASV)模式中,数据传输的通道的建立是由FTP客户端发起的,他使用一个大于1024的端口连接服务器的1024以上的某一个端口)

     ◆ContentLength - 设置这个属性对于FTP服务器是有用的,但是客户端不使用它,因为FTP WebRequest忽略这个属性,所以在这种情况下,该属性是无效的。但是如果我们设置了这个属性,FTP服务器将会提前预知文件的大小(在upload时会有这种情况)

     ◆Method - 指定当前请求是什么命令(upload,download,filelist等)。这个值定义在结构体WebRequestMethods.FTP中。以上介绍C# FTP WebRequest对象。

3. 可能用到的参数实例

    string localDir = @"C:\Users\Public\Downloads\FileDownLoadCacheFromFTP";
            if (!Directory.Exists(localDir))
            {
                Directory.CreateDirectory(localDir);
            }
            string targetDir = "ftp://172.17.3.110/LocalUser/";
            string detailDir = "2012/12/2012121100006/";
            string ftpFile = "A-06_X001-A.txt";
            string username = "User2012";
            string password = "123456";

4. FTP文件操作

    FtpWebRequest实例获取

View Code
/// 得到ftp的操作实例 FtpWebRequest
    /// </summary>
    /// <param name="URI">ftp文件目录</param>
    /// <param name="username">ftp用户名</param>
    /// <param name="password">ftp密码</param>
    /// <returns></returns>
    public static FtpWebRequest GetRequest(string URI, string username, string password)
    {
        FtpWebRequest result = (FtpWebRequest)FtpWebRequest.Create(URI);
        //提供身份验证信息(用户名和密码)
        result.Credentials = new System.Net.NetworkCredential(username, password);
        //设置请求完成之后是否保持到ftp的连接,默认true
        result.KeepAlive = true;
        return result;
    }

  上传文件到ftp服务器

View Code
 /// ftp文件上传
    /// </summary>
    /// <param name="info">要上传的文件</param>
    /// <param name="targetDir">ftp服务器根目录(ftp://ip/文件夹路径/ &&以'/'结束)</param>
    /// <param name="detailDir">子目录(年/月/文件单号/&&以'/'结束)</param>
    /// <param name="username">ftp用户名</param>
    /// <param name="password">ftp密码</param>
    public static bool ftpUpload(FileInfo info, string targetDir,string detailDir,string username, string password)
    {
        bool flag = true;
       
        //判断目录是否存在(不存在则创建)
        FtpCheckDirectoryExist(targetDir, detailDir, username, password);

        string target;//创建临时文件名
        target = Guid.NewGuid().ToString();
        string URI = targetDir + detailDir + target;//文件目录
        System.Net.FtpWebRequest ftp = GetRequest(URI, username, password);

        ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile;//设置要执行的ftp命令类型
        ftp.UseBinary = true;//指定文件传输的数据类型
        ftp.UsePassive = true;//设置ftp的传输模式为主动模式
        //ftp.ContentLength = info.Length;//告诉ftp文件的大小
        const int BufferSize = 2048;//设置缓存大小为2kb
        byte[] content = new byte[BufferSize - 1 + 1];
        int dataRead;
        using (FileStream fs = info.OpenRead())
        {
            try
            {
                //把上传的文件写入流
                using (Stream rs = ftp.GetRequestStream())
                {
                    do
                    {
                        dataRead = fs.Read(content, 0, BufferSize);
                        rs.Write(content, 0, dataRead);
                    }
                    while (dataRead >= BufferSize);//每次从fs中读2kb,直到最后一次读取dataRead的值小于2kb
                    rs.Close();
                }
            }
            catch (Exception ex) 
            {
                flag = false;
            }
            finally { fs.Close(); }
        }

        ftp = null;
        ftp = GetRequest(URI, username, password);
        ftp.Method = System.Net.WebRequestMethods.Ftp.Rename;//重命名
        ftp.RenameTo = info.Name;

        try
        {
            ftp.GetResponse();
        }
        catch (Exception ex)
        {
            flag = false;
            ftp = GetRequest(URI, username, password);
            ftp.Method = System.Net.WebRequestMethods.Ftp.DeleteFile;
            ftp.GetResponse();
            throw ex;
        }
        finally { }
        ftp = null;

        return flag;
    }

  下载FTP服务器上的文件到本地 

View Code
 /// <summary>
    /// ftp文件下载
    /// </summary>
    /// <param name="targetDir">ftp服务器根目录(ftp://ip/文件夹路径/ &以'/'结束)</param>
    /// <param name="detailDir">子目录(年/月/文件单号/&&以'/'结束)</param>
    /// <param name="FtpFileName">要下载的ftp文件的文件名</param>
    /// <param name="localDir">本地的缓存路径(用来暂时性保存从ftp服务器上下载的文件)</param>
    /// <param name="username">ftp用户名</param>
    /// <param name="password">ftp密码</param>
    public static void DownloadftpFile(string targetDir, string detailDir, string FtpFileName, string localDir, string username, string password)
    {
        string URI = targetDir.Trim() + detailDir.Trim() + FtpFileName;
        string tmpname = Guid.NewGuid().ToString();
        //本地路径不存在时则创建 
        if (!Directory.Exists(localDir))
        {
            Directory.CreateDirectory(localDir);
        }
        string localfile = localDir + @"\" + tmpname;//临时文件名称

        System.Net.FtpWebRequest ftp = GetRequest(URI, username, password);
        ftp.Method = System.Net.WebRequestMethods.Ftp.DownloadFile;
        ftp.UseBinary = true;
        ftp.UsePassive = false;

        using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
        {
            using (Stream responseStream = response.GetResponseStream())
            {
                using (FileStream fs = new FileStream(localfile, FileMode.CreateNew))
                {
                    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));//逐次读取文件(每次读2kb)
                        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
                        System.IO.File.Delete(localfile);
                        throw;
                    }
                }
                responseStream.Close();
            }
            response.Close();
        }
        try
        {
            System.IO.File.Delete(localDir + @"\" + FtpFileName);
            System.IO.File.Move(localfile, localDir + @"\" + FtpFileName);
        }
        catch
        {

        }

        ftp = null;

        try
        {
            //将文件显示给用户(打开或下载)
            string fileFullName = localDir + "\\" + FtpFileName;//文件的全名
            FileInfo file = new FileInfo(fileFullName);
            if (System.IO.File.Exists(fileFullName))
            {
                //将文件下载到客户机
                HttpContext.Current.Response.Clear();
                HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpContext.Current.Server.UrlEncode(FtpFileName));
                HttpContext.Current.Response.ContentType = "application/octet-stream";
                HttpContext.Current.Response.Filter.Close();
                HttpContext.Current.Response.WriteFile(file.FullName);
                HttpContext.Current.Response.End();
            }
        }
        catch { };
    }

  删除FTP服务器上的文件

View Code
 /// <summary>
        /// 删除FTP文件
        /// </summary>
        /// <param name="targetDir"></param>
        /// <param name="detailDir"></param>
        /// <param name="FtpFile"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        public static  void DeleteFTPFile(string targetDir, string detailDir, string FtpFile, string username, string password)
        {
            string URI = targetDir + detailDir + FtpFile;
            System.Net.FtpWebRequest ftp = GetRequest(URI, username, password);
            ftp.Method = System.Net.WebRequestMethods.Ftp.DeleteFile;
            ftp.GetResponse();
        }

  判断FTP文件的目录是否存在,不存在则创建 

View Code
 /// 判断文件的目录是否存,不存则创建
    /// </summary>
    /// <param name="targetDir"></param>
    /// <param name="detailDir"></param>
    /// <param name="username"></param>
    /// <param name="password"></param>
    public static void FtpCheckDirectoryExist(string targetDir,string detailDir,string username,string password)
    {
        string ftppath = targetDir + detailDir;
        if (ftppath.LastIndexOf('/') == ftppath.Length - 1)
            ftppath = ftppath.Substring(0, ftppath.Length - 1);
        int index = ftppath.IndexOf("//");
        string strdir = ftppath.Substring(index+2);

        string[] dirs = null;
        if (strdir.IndexOf('/') != -1)
        {
            dirs = strdir.Split('/');
            string curDir = "ftp://"+dirs[0];//ftp地址
            for (int i = 1; i < dirs.Length; i++)
            {
                curDir +="/"+ dirs[i];
                if(!ftpExitsDirectory(curDir,username,password))//判断目录是否存在
                {
                    FtpMakeDir(curDir, username, password);//创建目录
                }
            
            }

        }
        else
        {
            dirs[0] = strdir;
        }
        
    }

  判断FTP服务器上的目录是否存在

View Code
 /// 判断ftp路径是否存在
    /// </summary>
    /// <param name="Dir">目标路径</param>
    /// <param name="username"></param>
    /// <param name="password"></param>
    /// <returns></returns>
    public static bool ftpExitsDirectory(string Dir, string username, string password)
    {
        bool flag = true;
        try
        {
            string URI = Dir;
            System.Net.FtpWebRequest ftp = GetRequest(URI, username, password);
            ftp.Method = WebRequestMethods.Ftp.ListDirectory;
            FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();

            response.Close();
        }
        catch (Exception ex)
        {
            flag = false;
        }
        return flag;
    }

  在FTP服务器上创建目录(与创建本地目录不同的是FTP目录必须层级递进创建) 

View Code
 /// 创建ftp路径
    /// </summary>
    /// <param name="targetDir"></param>
    /// <param name="detailDir"></param>
    /// <param name="username"></param>
    /// <param name="password"></param>
    public static void FtpMakeDir(string dir, string username, string password)
    {

        try
        {
            if (dir.LastIndexOf('/') == dir.Length - 1)
                dir = dir.Substring(0, dir.Length - 1);
            Uri uri = new Uri(dir);
            FtpWebRequest FTP = (FtpWebRequest)FtpWebRequest.Create(uri);
            FTP.Credentials = new NetworkCredential(username, password);
            FTP.Proxy = null;
            FTP.KeepAlive = false;
            FTP.Method = WebRequestMethods.Ftp.MakeDirectory;
            FTP.UseBinary = true;
            FtpWebResponse response = FTP.GetResponse() as FtpWebResponse;
            response.Close();

        }
        catch (Exception ex)
        {

        }
    }

 

  

 

posted on 2012-12-21 09:50  eye_like  阅读(533)  评论(0)    收藏  举报