如何在一个FTP连接中执行多个方法

时间:2014-02-26 18:02:24

标签: c# asp.net-mvc-3

我已将代码设置为使用FTP文件到FTP服务器进行FTP PUT。首先,我有一个方法来检查文件是否存在于目标位置。然后,如果它,我有另一种方法删除该文件。然后我执行FTP PUT到目标位置。

目前,我通过设置3个独立的FTP连接到同一台服务器来执行这3种方法。但是,我希望通过一次连接到服务器来执行所有3种方法。原因是因为在打开到同一FTP服务器的多个连接后出现以下错误:“远程主机强行关闭现有连接。”

以下是3个功能。第一种方法GetFileFromRemoteServer用于查看目标路径上FTP服务器上是否存在文件。我在某些情况下使用正则表达式来获得部分名称匹配,或者在其他情况下只使用全名匹配。

我在网上研究过,有人说可以使用相同的ftp请求对象,只需执行所需的所有方法,然后关闭连接。我试着看看它是否在同一个请求对象上执行多个方法,并且我收到了这个错误:在提交请求后无法执行此操作。

有没有办法使用一个连接到服务器来执行所有这些?

谢谢,非常感谢您的帮助!

public static List<FTPLineResult> GetFileFromRemoteServer(bool isSsl, string username, string password, string fileName, string dir, Regex regexPattern,
        bool getSingleFile = false)
{
        var output = new List<FTPLineResult>();
        var parser = new FTPLineParser();
        var isDone = false;

        var request = (FtpWebRequest)WebRequest.Create(dir);
        request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
        request.ConnectionGroupName = ConfigurationManager.AppSettings["ftpConnectionGroup"];
        request.KeepAlive = true;

        request.Credentials = new NetworkCredential(username, password);
        request.UsePassive = true;

        if (isSsl)
        {
            request.EnableSsl = true;
        }
        else
        {
            request.EnableSsl = false;
        }

        using (var response = (FtpWebResponse)request.GetResponse())
        {
            using (var responseStream = response.GetResponseStream())
            {
                using (var reader = new StreamReader(responseStream, Encoding.ASCII))
                {
                    while (!isDone && !reader.EndOfStream)
                    {
                        var result = parser.Parse(reader.ReadLine());

                        //if "*" is in file name, which means get partial match, replacing * with real file name content
                        if (regexPattern != null)
                        {
                            if (regexPattern.IsMatch(result.Name.ToLower().Trim()))
                            {
                                output.Add(result);
                            }

                        }

                        else if (result.Name.ToLower().Trim() == fileName.ToLower().Trim())
                        {
                            output.Add(result);

                            isDone = true;
                        }
                    }

                    return output;
                }
            }
        }
    }


private void DeleteExistingTargetFile()
{
        // Get the object used to communicate with the server.
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_params.FinalFolderTarget);
        request.Method = WebRequestMethods.Ftp.DeleteFile;
        request.Credentials = new NetworkCredential(_params.Username, _params.Password);
        request.UsePassive = true;

        request.ConnectionGroupName = ConfigurationManager.AppSettings["ftpConnectionGroup"];
        request.KeepAlive = true;

        if (_params.IsSsl)
        {
            request.EnableSsl = true;
        }
        else
        {
            request.EnableSsl = false;
        }

        using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
        {
            var status = response.StatusDescription;
        }
    }

private void DoFtpPut(Dictionary<StatusEnum, string> statusDict)
{
        int buffLength = 2048;
        byte[] buff = new byte[buffLength];
        System.IO.FileInfo _FileInfo = new System.IO.FileInfo(_params.SourceFilename);

        var request = (FtpWebRequest)WebRequest.Create(new Uri(_params.TargetFilename));
        request.Method = WebRequestMethods.Ftp.UploadFile;
        request.ConnectionGroupName = ConfigurationManager.AppSettings["ftpConnectionGroup"];
        request.KeepAlive = true;

        request.Credentials = new NetworkCredential(_params.Username, _params.Password);
        request.UsePassive = true;

        if (_params.IsSsl)
        {
            request.EnableSsl = true;
        }
        else
        {
            request.EnableSsl = false;
        }

        using (var _Stream = request.GetRequestStream())
        {
            //read file one chunk at a time in order to avoid out of memory exception
            using (var fileStream = _FileInfo.OpenRead())
            {
                var contentLen = fileStream.Read(buff, 0, buffLength);

                while (contentLen != 0)
                {
                    _Stream.Write(buff, 0, contentLen);
                    contentLen = fileStream.Read(buff, 0, buffLength);
                }
            }
        }

        statusDict[StatusEnum.ftpStatus] = Constants.SUCCESS_STATUS;
    }

1 个答案:

答案 0 :(得分:0)

我无法找到使用FtpWebRequest类只使用一个连接来执行FTPPUT的方法。但是,使用FtpLib库允许我完全按照我想要的方式执行,这是检查ftp服务器目标位置上是否存在文件,如果确实存在,则删除它,然后执行ftp put,最后使用重命名将文件移动到最终位置。

这是我下载ftplib库的地方:ftplib.codeplex.com

以下是以下代码:

using (FtpConnection ftp = new FtpConnection(host, _params.Username, _params.Password))
{

            try
            {
                ftp.Open(); /* Open the FTP connection */
                ftp.Login(); /* Login using previously provided credentials */

                ftp.PutFile(_params.SourceFilename, _params.TargetFilename); /* upload /incoming/file.txt as file.txt to current executing directory, overwrite if it exists */

                if (!ftp.DirectoryExists(_params.FinalDir)) /* check that a directory exists */
                {
                    ftp.CreateDirectory(_params.FinalDir);
                }

                if (ftp.FileExists(_params.FinalLocation))
                {
                    ftp.RemoveFile(_params.FinalLocation);
                }

                ftp.RenameFile(target, _params.FinalLocation);

                statusDict[StatusEnum.ftpStatus] = Constants.SUCCESS_STATUS;

            }
            catch (Exception ex)
            {
                statusDict[StatusEnum.ftpStatus] = Constants.ERROR_STATUS;
            }
        }