C#下载FTP上文件夹下面的文本文件。
问题:FTP中的文本文件如果正在被写入,使用socket开发的FTP下载功能照样能把文件下载下来,这样造成了文本没写入完成就已经被下载了。下载的时候也不报个异常,无法捕捉异常处理。这个情况有什么方法可以避免呢?求大神。。

解决方案 »

  1.   


    大神们帮一下忙啦!!  要不送个C#操作FTP的API给小弟,至少操作文件的时候能捕获文件正在被另一个进程打开的异常。自己顶下先!不然就沉啦!
      

  2.   

    我以前写的。。给你参考参考。。
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net;
    using System.IO;namespace FTP_Up_Down
    {
        public partial class FTP : Form
        {
            public FTP()
            {
                InitializeComponent();
            }
            //定义字段
            string ftpServerIP;//服务器IP        private void FTP_Load(object sender, EventArgs e)
            {
                ftpServerIP = "127.0.0.1";
                this.textBox_IP.Text = ftpServerIP;
            }        //显示服务器已存在的文件
            private void button_ShowList_Click(object sender, EventArgs e)
            {   
                this.button_ShowList.Text="刷新";
                string[] filenames = GetFilesList();//调用“文件列表”
                listBox_FlieList.Items.Clear();
                try
                {
                    foreach (string filename in filenames)
                    {
                        listBox_FlieList.Items.Add(filename);
                    }
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return;
                }
            }        //文件列表
            public string[] GetFilesList()
            {
                string[] downloadFiles;          
                StringBuilder result = new StringBuilder();//定义一个可变字符串字段      
                FtpWebRequest reqFTP;//实现文件传输协议(FTP)客户端
                try
                {       
                    reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/"));//为指定的URI创建FtpWebRequest实例      
                    reqFTP.UseBinary = true;    //采用二进制数据类型传输    
                    reqFTP.Method = WebRequestMethods.Ftp.ListDirectory; //获取FTP服务器上的文件的简短列表   
                    WebResponse response = reqFTP.GetResponse();    //提供来自URI的响应    
                    StreamReader reader = new StreamReader(response.GetResponseStream());  //从字节流中读取字符       
                    string line = reader.ReadLine(); //持续读取文件名以便列表显示
                    while (line != null)
                    {
                        result.Append(line);
                        result.Append("\n");
                        line = reader.ReadLine();
                    }           
                    result.Remove(result.ToString().LastIndexOf('\n'), 1); //去除最后一个多余的换行符('\n')
                    reader.Close();//关闭读文件流
                    response.Close();   
                    return result.ToString().Split('\n'); //返回文件名列表结果
                }
                catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show(ex.Message);
                    downloadFiles = null;
                    return downloadFiles;
                }
            }        //上传
            private void button_Up_Click(object sender, EventArgs e)
            {
                OpenFileDialog opFilDlg = new OpenFileDialog();
                if (opFilDlg.ShowDialog() == DialogResult.OK)
                {     
                    UpLoad(opFilDlg.FileName); //调用“上传文件”     
                    string[] filenames = GetFilesList(); //刷新文件名列表
                    listBox_FlieList.Items.Clear();
                    foreach (string filename in filenames)
                    {
                        listBox_FlieList.Items.Add(filename);
                    }
                    MessageBox.Show("文件上传结束。");
                }
            }        //上传文件
            private void UpLoad(string filename)
            {
                FileInfo fileInf = new FileInfo(filename);  
                FtpWebRequest reqFTP;   //实现文件传输协议(FTP)客户端
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileInf.Name));//为指定的URI创建FtpWebRequest对象      
                reqFTP.KeepAlive = false;  //默认为true,在一个命令之后被执行连接不会被关闭
                reqFTP.Method = WebRequestMethods.Ftp.UploadFile;//指定执行上传命令
                reqFTP.UseBinary = true;  //指定数据传输类型(二进制)
                reqFTP.ContentLength = fileInf.Length;//上传文件时通知服务器文件的大小
                int buffLength = 2048; //缓冲大小设置为2kb
                byte[] buff = new byte[buffLength];
                int contentLen;     
                FileStream fs = fileInf.OpenRead(); //打开一个文件流 (System.IO.FileStream) 来读上传的文件
                try
                {
                    Stream strm = reqFTP.GetRequestStream();//检索用于向FTP服务器上载数据的流
                    contentLen = fs.Read(buff, 0, buffLength); //每次从文件流中读入2kb(缓冲大小)
                    while (contentLen != 0)  //持续进行文件流的读写,直至全部结束
                    {         
                        strm.Write(buff, 0, contentLen); //将所读取的文件流写入到上传流的字节序列
                        contentLen = fs.Read(buff, 0, buffLength);
                    }      
                    strm.Close(); //关闭文件流和上传流
                    fs.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "文件上传出错。");
                }
            }        //下载
            private void button_Down_Click(object sender, EventArgs e)
            {
                FolderBrowserDialog fldDlg = new FolderBrowserDialog();
                if (listBox_FlieList.Text.Trim().Length > 0)
                {
                    if (fldDlg.ShowDialog() == DialogResult.OK)
                    {             
                        DownLoad(fldDlg.SelectedPath, listBox_FlieList.Text.Trim());//调用“下载文件”
                    }
                    MessageBox.Show("文件下载结束。");
                }
                else
                {
                    MessageBox.Show("请选择需要下载的文件。");
                }
            }        //下载文件
            private void DownLoad(string filePath, string fileName)
            {
                FtpWebRequest reqFTP;
                try
                {
                    //设置文件下载后的保存路径(文件夹):filePath
                    //命名下载后的文件名(可与原文件名不同):fileName
                    FileStream outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);
                    reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileName));
                    //指定执行下载命令
                    reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
                    reqFTP.UseBinary = true;          
                    FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); //返回FTP服务器响应         
                    Stream ftpStream = response.GetResponseStream();//检索从FTP服务器上发送的响应数据的流               
                    long cl = response.ContentLength;//获取从FTP服务器上接收的数据的长度
                    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 ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
    }
      

  3.   

    参考 C# 从FTP服务器下载文件到本地
      

  4.   

    我建议你使用我的  FTP帮助类
      

  5.   

    为什么不使用webclient呢,搞这么麻烦
      

  6.   

    Quote: 引用 2 楼 dengjiejie1990 的回复:

    我以前写的。。给你参考参考。。你好,非常感谢你的代码,这个代码结构是我想要的,但是我想提几个疑问:
    1.如果FTP上的文件正在被写入,会报异常吗?
    2.在哪里接收FTP的用户名密码、FTP存放文件的目录?
    3.如果我获取获取了FTP目录列表,在下载文件中需要一个for循环来遍历下载,这个代码该在哪里插入?
      

  7.   

    Quote: 引用 2 楼 dengjiejie1990 的回复:

    我以前写的。。给你参考参考。。
    quote]
    WebResponse response = reqFTP.GetResponse(); 
    程序执行到这一句的时候,报‘基础连接已经关闭: 连接被意外关闭’异常这个可以帮忙解决一下吗??
      

  8.   

    如果木有配置FTP。。那肯定是会报错的。。
      

  9.   

    你可以当前文件的状态是不是这个在写入,如果是写入的话就等待。
     /// <summary>
            /// 判断文档是否被使用
            /// </summary>
            /// <param name="fileName"></param>
            /// <returns></returns>
            public bool IsFileInUse(string fileName)
            {            bool inUse = true;            if (File.Exists(fileName))
                {                FileStream fs = null;                try
                    {                    fs = new FileStream(fileName, FileMode.Open, FileAccess.Read,                    FileShare.None);                    inUse = false;                }                catch
                    {                    // exception....                }                finally
                    {                    if (fs != null)                        fs.Close();                }                return inUse;//by yl  true表示正在使用,false没有使用            }            else
                {                return false;//文件不存在,肯定没有被使用            }        }
      

  10.   

    非常感谢各位!问题已经解决啦,我采用的方式是如果FTP上面的文件正在写入是不可以重命名的。