You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过FTP取回文件分发至多服务器时遇错误,求解决方案

问题:FTP大文件跨服务器备份分发的实现问题

核心需求

通过FTP取回130GB的文件,直接分发至两台备份服务器的网络共享路径;完成两台服务器的上传后,删除FTP服务器上的源文件;程序以服务形式运行在中间服务器上,且该服务器无本地缓存空间,无法先下载到本地再转发。


遇到的三类错误及对应实现尝试

1. 使用FtpWebRequest的异常

本地开发环境(以域账号作为服务身份调试)运行正常,但部署到测试环境后,在创建StreamWriter阶段抛出以下错误:

The underlying connection was closed: The server committed a protocol violation.

目标路径为\\fqdn\directory或\\192.168.123.123\directory$这类网络共享路径。

相关代码:

private bool CopyFTPToPath(string file, string path)
{
    try
    {
        string filePath = "ftp://" + Settings["Host"].Value + "/" + Settings["Path"].Value + "/" + file;
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(filePath);
        request.Method = WebRequestMethods.Ftp.DownloadFile;
        request.Credentials = new NetworkCredential("user", "pass");
        using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
        {
            using (Stream responseStream = response.GetResponseStream())
            {
                using (StreamReader reader = new StreamReader(responseStream))
                {
                    using (StreamWriter writer = new StreamWriter(path + "/" + file, false))
                    {
                        writer.Write(reader.ReadToEnd());
                    }
                }
            }
        }
        return File.Exists(path + "/" + file);
    catch(Exception ex)
    {
        Utility.LogError(ErrorType.Alert, ex);
    }
}

2. 使用WinSCP库的目录找不到异常

调用session.GetFileToDirectory时抛出System.IO.DirectoryNotFoundException,推测WinSCP无法直接识别网络共享路径作为本地目标目录。错误栈信息:

{System.IO.DirectoryNotFoundException: \\192.***.***.***\Path\Path
   at WinSCP.Session.DoGetFilesToDirectory(String remoteDirectory, String localDirectory, String filemask, Boolean remove, TransferOptions options, String additionalParams)
   at WinSCP.Session.GetEntryToDirectory(String remoteFilePath, String localDirectory, Boolean remove, TransferOptions options, String additionalParams)
   at WinSCP.Session.GetFileToDirectory(String remoteFilePath, String localDirectory, Boolean remove, TransferOptions options)
   at Program.RoutineTasks.Backup.CopyFTPToPath(String file, String path) in C:\Projects\Program\RoutineTasks\Backup.cs:line 114}

相关代码:

private bool CopyFTPToPath(string file, string path)
{
    try
    {
        string filePath = "ftp://" + Settings.Settings["Host"].Value + "/" + Settings["Path"].Value + "/" + file;
        SessionOptions sessionOptions = new SessionOptions() {
            Protocol = Protocol.Ftp,
            HostName = Settings.Settings["Host"].Value,
            UserName = "user",
            Password = "pass"
        };
        using(Session session = new Session())
        {
            session.Open(sessionOptions);
            TransferOptions transferOptions = new TransferOptions();
            transferOptions.TransferMode = TransferMode.Binary;
            TransferEventArgs result = session.GetFileToDirectory(filePath, path,false,transferOptions);
        }
        return File.Exists(path + "/" + file);
    catch(Exception ex)
    {
        Utility.LogError(ErrorType.Alert, ex);
    }
}

3. 流处理思路的内存优化需求

为避免本地缓存,尝试直接通过流将FTP文件写入网络路径,但当前逐字符读写的方式效率极低,且仍存在内存耗尽风险。相关代码:

using(Session session = new Session())
{
    session.Open(sessionOptions);
    TransferOptions transferOptions = new TransferOptions();
    transferOptions.TransferMode = TransferMode.Binary;
    using (StreamReader reader = new StreamReader(session.GetFile(filePath, transferOptions)))
    {
        using (StreamWriter writer = new StreamWriter(path + "/" + file, false))
        {
            while (!reader.EndOfStream)
            {
                writer.Write(reader.Read());
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Jingo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 18:30:13