使用C#从FTP服务器以多个线程的块形式下载单个文件

我只想使用C#从FTP服务器的多个线程中的多个段中下载单个文件。

是否可以像HttpWebRequest中那样提供文件下载范围?

tou999999 回答:使用C#从FTP服务器以多个线程的块形式下载单个文件

首先免责声明: 多任务处理不是不是神奇的“更快”子弹。如果将其应用于错误的问题,则最终代码会变得比普通的单任务/顺序方法更复杂/更容易出错,对内存的要求更高,并且实际上更慢。通常,一项长期运行的替代任务是强制性的。但是大规模并行化仅在非常特殊的情况下进行。

常规文件操作受磁盘或网络限制。多任务处理不会对磁盘​​或网络绑定的操作增加任何加速。确实可能会导致速度降低,因为NCQ和类似功能必须理顺您的随机访问请求。有了Netowrking,有时 会有所帮助。 某些服务器确实设置了“每个连接”限制,因此可以通过单独的下载将下载分成多个段,从而可以加快网络速度。 但是可以肯定的是,这里确实如此。考虑除Speed Rant的第1点之外的所有内容。

假设FTPWebRequest仍然是您正在使用的类,则看起来ContentLenghtContentOffset可能是您正在寻找的机器人。基本上,它的使用类似于子字符串-每个连接/子请求都从Y偏移中提取X个字节。

,

您可以使用FtpWebRequest.ContentOffset来指定起始偏移量。

但是FtpWebRequest.ContentLength未实现。要解决此问题,一旦收到所需的字节数,您就必须中止下载。

const string name = "bigfile.dat";
const int chunks = 3;
const string url = "ftp://example.com/remote/path/" + name;
NetworkCredential credentials = new NetworkCredential("username","password");

Console.WriteLine("Starting...");

FtpWebRequest sizeRequest = (FtpWebRequest)WebRequest.Create(url);
sizeRequest.Credentials = credentials;
sizeRequest.Method = WebRequestMethods.Ftp.GetFileSize;
long size = sizeRequest.GetResponse().ContentLength;
Console.WriteLine($"File has {size} bytes");
long chunkLength = size / chunks;

List<Task> tasks = new List<Task>();

for (int chunk = 0; chunk < chunks; chunk++)
{
    int i = chunk;
    tasks.Add(Task.Run(() =>
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
            request.Credentials = credentials;
            request.Method = WebRequestMethods.Ftp.DownloadFile;
            request.ContentOffset = chunkLength * i;
            long toread = (i < chunks - 1) ? chunkLength : size - request.ContentOffset;
            Console.WriteLine(
                $"Downloading chunk {i + 1}/{chunks} with {toread} bytes ...");

            using (Stream ftpStream = request.GetResponse().GetResponseStream())
            using (Stream fileStream = File.Create(name + "." + i))
            {
                byte[] buffer = new byte[10240];
                int read;
                while (((read = (int)Math.Min(buffer.Length,toread)) > 0) &&
                       ((read = ftpStream.Read(buffer,read)) > 0))
                {
                    fileStream.Write(buffer,read);
                    toread -= read;
                }
            }
            Console.WriteLine($"Downloaded chunk {i + 1}/{chunks}");
        }));
}

Console.WriteLine("Started all chunks downloads,waiting for them to complete...");
Task.WaitAll(tasks.ToArray());

Console.WriteLine("Done");
Console.ReadKey();
本文链接:https://www.f2er.com/3159232.html

大家都在问