繁体   English   中英

使用 .NET Core 中的一个连接通过 FTP 下载多个文件

[英]Download multiple files over FTP using one connection in .NET Core

我正在尝试仅使用一个打开的连接将多个文件下载到 memory。

我从这个文档中知道: https://docs.microsoft.com/en-us/dotnet/api/system.net.ftpwebrequest.keepalive - FtpWebRequest默认KeepAlive为 true。

如果不应该破坏与服务器的连接; 否则为假。 默认值是true。

我创建了这段代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;

namespace ConsoleApp23
{
    class Program
    {

        static void Main(string[] args)
        {
            String[] files = FTPListTree("ftp://server.com", "user", "password");

            for (int i = 0; i <= files.Count() - 1; i++)
            {
                string path = files[i].ToString();
                var request = (FtpWebRequest)WebRequest.Create(path);
                request.Method = WebRequestMethods.Ftp.DownloadFile;
                request.Credentials = new NetworkCredential("user", "password");
                request.Timeout = 100000;
                request.KeepAlive = true;
                request.ConnectionGroupName = "DownloadFilesGroup";
                request.ServicePoint.ConnectionLimit = 8;

                using (var response = (FtpWebResponse)request.GetResponse())
                {
                    using (var stream = response.GetResponseStream())
                    {
                        var ms = new MemoryStream();
                        stream.CopyTo(ms);
                        var a = ms.ToArray();
                        string ss = Encoding.UTF8.GetString(a);
                        Console.WriteLine(ss);
                    }
                }
            }
        }

        public static String[] FTPListTree(String ftpUri, String user, String pass)
        {

            try
            {
                List<String> files = new List<String>();
                Queue<String> folders = new Queue<String>();
                folders.Enqueue(ftpUri);

                while (folders.Count > 0)
                {
                    String fld = folders.Dequeue();
                    List<String> newFiles = new List<String>();

                    FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(fld);
                    ftp.Timeout = 20000;
                    ftp.Credentials = new NetworkCredential(user, pass);
                    ftp.Method = WebRequestMethods.Ftp.ListDirectory;

                    using (StreamReader resp = new StreamReader(ftp.GetResponse().GetResponseStream()))
                    {
                        String line = resp.ReadLine();
                        while (line != null)
                        {
                            newFiles.Add(line.Trim());
                            line = resp.ReadLine();
                        }
                    }

                    ftp = (FtpWebRequest)FtpWebRequest.Create(fld);
                    ftp.Timeout = 20000;
                    ftp.Credentials = new NetworkCredential(user, pass);
                    ftp.Method = WebRequestMethods.Ftp.ListDirectory;

                    using (StreamReader resp = new StreamReader(ftp.GetResponse().GetResponseStream()))
                    {
                        String line = resp.ReadLine();
                        while (line != null)
                        {
                            if (!Path.HasExtension(line))
                            {
                                String dir = newFiles.First(x => line.EndsWith(x));
                                newFiles.Remove(dir);
                                folders.Enqueue(fld + dir + "/");
                            }
                            line = resp.ReadLine();
                        }
                    }
                    files.AddRange(from f in newFiles select fld + f);
                }
                return files.ToArray();
            }
            catch (Exception e)
            {
                throw;
            }
        }
    }
}

这是一种正确的处理方式吗? 我似乎找不到任何关于如果处理response或响应 stream 将关闭控制连接,keepalive 将保持打开状态的文档。

有什么方法可以在运行它时记录它,所以我可以看到 FTP 调用? 我自己无权访问 FTP 服务器。

更新

我实际上已经用测试 FTP 和上面的代码对此进行了测试,即使它有KeepAlive=true ,它在每个请求上都使用新连接。 我已经使用 Fluent API: https://github.com/robinrodricks/FluentFTP/blob/master/FluentFTP.CSharpExamples/DownloadManyFiles.cs创建了一个 PoC,它可以正确完成:连接一次,下载文件。 我感觉FtpWebRequest就是这种情况。 我不明白KeepAlive和它的作用。 也许它重用了 TCP 连接,这本身就是一件好事,但它使用 TCP 连接来登录每个请求。

有谁知道这是否可能使用FtpWebRequest ,而不是登录每个新请求,例如 Fluent FTP API? 我错过了什么吗?

可以在此处查看 FTP 日志的示例FTP日志

FTP 是 FileZilla Server 0.9.60 beta。

.NET Core: https://github.com/dotnet/runtime/issues/23256中似乎没有实现 FTP 连接重用

由于*WebRequest API 实际上已经过时,它可能永远不会过时。


使用 .NET 框架,它可以按预期工作:
FTP C#中的多个文件,无需重新建立连接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM