English 中文(简体)
FTP与进步的下载档案——总收
原标题:Download file from FTP with Progress - TotalBytesToReceive is always -1?

我正试图从一个有进步的快车库下载一个档案。

档案正在下载,而“进步”活动正在打电话,但“总产值”除外。 收受 -1. 总比特增加,但我无法计算没有总额的百分比。

我认为,我可以通过其他卑鄙的指挥,找到档案规模,但我不禁要问,为什么这样做?

我的法典:

FTPClient request = new FTPClient();
request.Credentials = credentials;
request.DownloadProgressChanged += new DownloadProgressChangedEventHandler(request_DownloadProgressChanged);
//request.DownloadDataCompleted += new DownloadDataCompletedEventHandler(request_DownloadDataCompleted);
request.DownloadDataAsync(new Uri(folder + file));
while (request.IsBusy) ;

........

static void request_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    if (e.TotalBytesToReceive == -1)
    {
        l.reportProgress(-1, FormatBytes(e.BytesReceived) + " out of ?" );
    }
    else
    {
        l.reportProgress(e.ProgressPercentage, "Downloaded " + FormatBytes(e.BytesReceived) + " out of " + FormatBytes(e.TotalBytesToReceive) + " (" + e.ProgressPercentage + "%)");
    }
}

........

class FTPClient : WebClient
{
    protected override WebRequest GetWebRequest(System.Uri address)
    {
        FtpWebRequest req = (FtpWebRequest)base.GetWebRequest(address);
        req.UsePassive = false;
        return req;
    }
}

感谢。

问题回答

因此,我有同样的问题。 我首先要提一下档案规模。

        // Get the object used to communicate with the server.
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create("URL");
        request.Method = WebRequestMethods.Ftp.GetFileSize;
        request.Credentials = networkCredential;
        FtpWebResponse response = (FtpWebResponse)request.GetResponse();

        Stream responseStream = response.GetResponseStream();
        bytes_total = response.ContentLength; //this is an int member variable stored for later
        Console.WriteLine("Fetch Complete, ContentLength {0}", response.ContentLength);
        response.Close();

        webClient = new MyWebClient();
        webClient.Credentials = networkCredential; ;
        webClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(FTPDownloadCompleted);
        webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FTPDownloadProgressChanged);
        webClient.DownloadDataAsync(new Uri("URL"));

然后是回击中的数学。

private void FTPDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
     progressBar.Value = (int)(((float)e.BytesReceived / (float)bytes_total) * 100.0);
}

总的说来,<代码>WebClient并不知道总下载量。 因此,通常请在FTP上-1

Note that the behavior actually contradicts the .NET documentation, which says for FtpWebResponse.ContentLength (where the value of TotalBytesToReceive comes from):

如要求使用<代码>DownloadFile方法,如果下载的文档含有数据,则该财产为零以上,如果是空的,则该财产为零。

但是,你会很容易发现这方面的许多问题,实际上表明行为并非总是如实记录。 方法具有有意义的价值。

<代码>FtpWebRequest/WebClient未明确试图发现其下载的卷宗数量。 所有这些都是为了研究<代码>(xxx bytes). string in 125/150/code> Responses to RETR。 FTP RFC没有规定服务器应包括这种信息。 ProFTPD(见 in src/data.c>和 vsftpd(见handle_retr in postlogin.c。 其他通用的FTP服务器(IIS、FilZilla)没有这样做。


如果您的服务器不提供大小信息,你就必须在下载前询问大小分析。 使用FtpWebRequest<>>>>:

private void button1_Click(object sender, EventArgs e)
{
    // Run Download on background thread
    Task.Run(() => Download());
}

private void Download()
{
    try
    {
        const string url = "ftp://ftp.example.com/remote/path/file.zip";
        NetworkCredential credentials = new NetworkCredential("username", "password");

        // Query size of the file to be downloaded
        WebRequest sizeRequest = WebRequest.Create(url);
        sizeRequest.Credentials = credentials;
        sizeRequest.Method = WebRequestMethods.Ftp.GetFileSize;
        int size = (int)sizeRequest.GetResponse().ContentLength;

        progressBar1.Invoke(
            (MethodInvoker)(() => progressBar1.Maximum = size));

        // Download the file
        WebRequest request = WebRequest.Create(url);
        request.Credentials = credentials;
        request.Method = WebRequestMethods.Ftp.DownloadFile;

        using (Stream ftpStream = request.GetResponse().GetResponseStream())
        using (Stream fileStream = File.Create(@"C:localpathfile.zip"))
        {
            byte[] buffer = new byte[10240];
            int read;
            while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                fileStream.Write(buffer, 0, read);
                int position = (int)fileStream.Position;
                progressBar1.Invoke(
                    (MethodInvoker)(() => progressBar1.Value = position));
            }
        }
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message);
    }
}

“enterography

The core download code is based on:
Upload and download a binary file to/from FTP server in C#/.NET

FTP 给你像吉大港山区这样的内容,你自己或许会做得更好。

FtpWebRequest FTPWbReq = WebRequest.Create("somefile") as FtpWebRequest;
FTPWbReq .Method = WebRequestMethods.Ftp.GetFileSize;

FtpWebResponse FTPWebRes = FTPWbReq.GetResponse() as FtpWebResponse;
long length = FTPWebRes.ContentLength;
FTPWebRes.Close();




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...