从 FTP 下载文件并有进度 - TotalBytesToReceive 始终为 -1?
我正在尝试从带有进度条的 FTP 服务器下载文件。
文件正在下载,并且 ProgressChanged 事件正在调用,但事件 args TotalBytesToReceive 始终为 -1 除外。 TotalBytes 增加,但如果没有总数,我无法计算百分比。
我想我可以通过其他 ftp 命令找到文件大小,但我想知道为什么这不起作用?
我的代码:
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;
}
}
。
I am trying to download a file from an FTP server with a progress bar.
The file is downloading, and the ProgressChanged event is calling, except in the event args TotalBytesToReceive is always -1. TotalBytes increases, but I am unable to calculate the percentage without the total.
I imagine I could find the file size through other ftp commands, but I wonder why this doesn't work?
My code:
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;
}
}
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
所以我有同样的问题。我通过首先检索文件大小来解决这个问题。
然后在回调中进行数学计算。
So I had the same issue. I got around it by retrieving the file size first.
Then do the math in the callback.
使用 FTP 协议,
WebClient
通常不知道总下载大小。因此,使用 FTP 通常会得到-1
。请注意,该行为实际上与 .NET 文档相矛盾,该文档表示
FtpWebResponse.ContentLength
(TotalBytesToReceive
的值来自于此):但您会很容易地发现许多与此相关的问题,有效地表明该行为并不总是如记录的那样。
FtpWebResponse.ContentLength
仅对GetFileSize
方法具有有意义的值。FtpWebRequest
/WebClient
不会明确尝试找出正在下载的文件的大小。它所做的只是尝试在对RETR
的125
/150
响应中查找(xxx bytes).
字符串> 命令。没有 FTP RFC 强制要求服务器应包含此类信息。 ProFTPD(请参阅data_pasv_open
src/data.c
)和 vsftpd(参见postlogin.c
中的handle_retr
)似乎包含此信息。其他常见的 FTP 服务器(IIS、FileZilla)不执行此操作。如果您的服务器没有提供大小信息,您必须在下载前自行查询大小。使用
FtpWebRequest
和任务
< /a>:核心下载代码基于:
在 C#/.NET 中向 FTP 服务器上传和下载二进制文件
With FTP protocol,
WebClient
in general does not know total download size. So you commonly get-1
with FTP.Note that the behavior actually contradicts the .NET documentation, which says for
FtpWebResponse.ContentLength
(where the value ofTotalBytesToReceive
comes from):But you will easily find out many of questions about this, effectively showing that the behavior is not always as documented. The
FtpWebResponse.ContentLength
has a meaningful value forGetFileSize
method only.The
FtpWebRequest
/WebClient
makes no explicit attempt to find out a size of the file that it is downloading. All it does is that it tries to look for(xxx bytes).
string in125
/150
responses toRETR
command. No FTP RFC mandates that the server should include such information. ProFTPD (seedata_pasv_open
insrc/data.c
) and vsftpd (seehandle_retr
inpostlogin.c
) seem to include this information. Other common FTP servers (IIS, FileZilla) do not do this.If your server does not provide size information, you have to query for size yourself before download. A complete solution using
FtpWebRequest
andTask
:The core download code is based on:
Upload and download a binary file to/from FTP server in C#/.NET
FTP 不会像 HTTP 那样为您提供内容大小,您可能最好自己做这件事。
FTP Wont give you content sizes like HTTP does, you would probably be better doing this on your own.