none
用FtpWebRequest定时下载文件的疑问 RRS feed

  • 问题

  • 各位大哥打扰了,我想实现定时从ftp服务器下载文件功能,于是使用了FtpWebRequest跟System.Timers.Timer类,我的疑问是为什么没等上一次文件下载完成又开始新一轮的下载了呢?

    我的代码如下

    private void button1_Click(object sender, EventArgs e)
        {
          myClient = new FTP_Client("localhost", "test", "password",21);
          System.Timers.Timer tim = new System.Timers.Timer(3000);
          tim.Elapsed += new System.Timers.ElapsedEventHandler(tim_Elapsed);
          tim.Start();
        }
    
        void tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
          myClient.Download("TaskFile/", Application.StartupPath, "aa.wmv");
          MessageBox.Show("aa");
        }
    

    FTP_Client类代码

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using System.Net;
    
    namespace FTP_TEST_SYNC
    {
      public class FTP_Client
      {
        private string strRemoteHost;
        private string strRemoteUser;
        private string strRemotePass;
        private int strRemotePort;
        /// <summary>
        /// 缺省构造函数
        /// </summary>
        public FTP_Client()
        {
          strRemoteHost = "";
          strRemoteUser = "";
          strRemotePass = "";
          strRemotePort = 21;
        }
        public FTP_Client(string remoteHost, string remoteUser, string remotePass, int remotePort)
        {
          strRemoteHost = remoteHost;
          strRemoteUser = remoteUser;
          strRemotePass = remotePass;
          strRemotePort = remotePort;
        }
        /// <summary>
        /// FTP服务器IP地址
        /// </summary>
        public string RemoteHost
        {
          get
          {
            return strRemoteHost;
          }
          set
          {
            strRemoteHost = value;
          }
        }
        /// <summary>
        /// FTP服务器端口
        /// </summary>
        public int RemotePort
        {
          get
          {
            return strRemotePort;
          }
          set
          {
            strRemotePort = value;
          }
        }
        /// <summary>
        /// 登录用户账号
        /// </summary>
        public string RemoteUser
        {
          set
          {
            strRemoteUser = value;
          }
        }
        /// <summary>
        /// 用户登录密码
        /// </summary>
        public string RemotePass
        {
          set
          {
            strRemotePass = value;
          }
        }
        //FTP内库函数
        FtpWebRequest reqFTP;
        Stream ftpStream;
        //建立文件输出流
        FileStream outputStream;
        FtpWebResponse response;
        /// <summary>
        /// FTP_下载文件
        /// </summary>
        /// <param name="remotePath">远程路径,右边带斜杠,若是根目录,则为空字符串</param>
        /// <param name="filePath">储存本地地址</param>
        /// <param name="fileName">下载文件名</param>
        public bool Download(string remotePath, string filePath, string fileName)
        {
          try
          {
            //创建连接
            string port = "";
            if (strRemotePort != 21)
            {
              port = ":" + strRemotePort.ToString();
            }
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + strRemoteHost + port + "/" + remotePath + fileName));
            reqFTP.KeepAlive = false;
            //向FTP服务器发送命令
            reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
            //传输类型
            reqFTP.UseBinary = true;
            reqFTP.UsePassive = false;
            //用户名和密码
            reqFTP.Credentials = new NetworkCredential(strRemoteUser, strRemotePass);
    
            response = (FtpWebResponse)reqFTP.GetResponse();
            //获取服务器上的流
            ftpStream = response.GetResponseStream();
            //接收数据长度
            long cl = response.ContentLength;
            //设置下载长度
            int bufferSize = 1024000;
    
            int readCount;
    
            byte[] buffer = new byte[bufferSize];
    
            readCount = ftpStream.Read(buffer, 0, bufferSize);
            outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);
            while (readCount > 0)
            {
              outputStream.Write(buffer, 0, readCount);
    
              readCount = ftpStream.Read(buffer, 0, bufferSize);
            }
    
            ftpStream.Close();
    
            outputStream.Close();
    
            response.Close();
    
            reqFTP.Abort();
            return true;
          }
          catch (Exception)
          {
            ftpStream.Close();
            outputStream.Close();
            response.Close();
            reqFTP.Abort();
            return false;
          }
        }
        public void Upload(string client_uid, string filename)
        {
          FileInfo fileInf = new FileInfo(filename);
          string uri = "ftp://" + strRemoteHost + "/" + fileInf.Name;
          FtpWebRequest reqFTP;  // 根据uri创建FtpWebRequest对象
          reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + strRemoteHost + "/LogFile/" + client_uid + fileInf.Name));  // ftp用户名和密码 
          reqFTP.Credentials = new NetworkCredential(strRemoteUser, strRemotePass);
          // 默认为true,连接不会被关闭 // 在一个命令之后被执行 
          reqFTP.KeepAlive = false;
          // 指定执行什么命令 
          reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
          // 指定数据传输类型 
          reqFTP.UseBinary = true;
          reqFTP.UsePassive = false;
          // 上传文件时通知服务器文件的大小 
          reqFTP.ContentLength = fileInf.Length;
          // 缓冲大小设置为2kb 
          int buffLength = 2048;
          byte[] buff = new byte[buffLength];
          int contentLen;
          // 打开一个文件流 (System.IO.FileStream) 去读上传的文件 
          FileStream fs = fileInf.OpenRead();
          try
          { // 把上传的文件写入流
            Stream strm = reqFTP.GetRequestStream();
            // 每次读文件流的2kb 
            contentLen = fs.Read(buff, 0, buffLength);
            // 流内容没有结束 
            while (contentLen != 0)
            {
              // 把内容从file stream 写入 upload stream 
              strm.Write(buff, 0, contentLen);
              contentLen = fs.Read(buff, 0, buffLength);
            }
            // 关闭两个流 
            strm.Close();
            fs.Close();
          }
          catch (Exception ex)
          {
            //MessageBox.Show(ex.Message, "Upload Error");
            fs.Close();
          }
        }
      }
    }
    
    我想实现的是文件下载完成之后再重新下载,而不是没完又开始新的下载
    2010年8月25日 5:38

答案

  • void tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {

    tim.enable=false;


          myClient.Download("TaskFile/", Application.StartupPath, "aa.wmv");
          MessageBox.Show("aa");

    tim.enable=true;
        }


    http://feiyun0112.cnblogs.com/
    2010年8月25日 8:08
    版主
  • feiyun0112 版主的方式更简单方便,使用时建议加上 try ... cath ... finally 保证失败后下一次任务能正常执行

     

    void tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
     try
     {
      tim.Enable = false;
      myClient.Download("TaskFile/", Application.StartupPath, "aa.wmv");
      MessageBox.Show("aa");
     }
     finally
     {
      tim.Enable = true;
     }
    }
    

     


    知识改变命运,奋斗成就人生!
    2010年8月25日 8:48
    版主

全部回复

  • 你好!

    Timer 的机制就是这样的,你在运行时判断一个上次是否执行完成就可以了。

    bool isWorking = false;
    
    private void button1_Click(object sender, EventArgs e)
    {
      myClient = new FTP_Client("localhost", "test", "password", 21);
      System.Timers.Timer tim = new System.Timers.Timer(3000);
      tim.Elapsed += new System.Timers.ElapsedEventHandler(tim_Elapsed);
      tim.Start();
    }
    
    void tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
      try
      {
        // 只有上一次任务完成后才会执行下面的代码
        if (!isWorking)
        {
          isWorking = true;
    
          myClient.Download("TaskFile/", Application.StartupPath, "aa.wmv");
          MessageBox.Show("aa");
    
          isWorking = false;
        }
      }
      catch
      {
        isWorking = false;
      }
    }
    


    知识改变命运,奋斗成就人生!
    • 已建议为答案 Huan Li 2010年8月25日 6:52
    2010年8月25日 6:36
    版主
  • void tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {

    tim.enable=false;


          myClient.Download("TaskFile/", Application.StartupPath, "aa.wmv");
          MessageBox.Show("aa");

    tim.enable=true;
        }


    http://feiyun0112.cnblogs.com/
    2010年8月25日 8:08
    版主
  • feiyun0112 版主的方式更简单方便,使用时建议加上 try ... cath ... finally 保证失败后下一次任务能正常执行

     

    void tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
     try
     {
      tim.Enable = false;
      myClient.Download("TaskFile/", Application.StartupPath, "aa.wmv");
      MessageBox.Show("aa");
     }
     finally
     {
      tim.Enable = true;
     }
    }
    

     


    知识改变命运,奋斗成就人生!
    2010年8月25日 8:48
    版主