如何用C# FtpWebRequest计算10GB文件FTP上传速率?解析缓冲区调优
嘿,很高兴能帮到你!针对你提出的两个问题——计算FTP上传速率,以及缓冲区大小优化的原理,我来详细解释一下:
一、如何计算FTP上传的传输速率
要计算传输速率,你需要跟踪已传输的总字节数和传输消耗的总时间,然后用总字节数除以时间得到每秒传输的字节数,再转换成更易读的单位(比如MB/s)。
具体实现步骤:
- 在上传开始前记录起始时间,同时初始化一个变量统计已传输的字节数;
- 每次成功写入数据到FTP流后,累加已传输的字节数;
- 上传完成后,计算耗时,再通过公式计算速率。
我已经把这个逻辑整合到你的代码里了,修改后的完整代码如下:
FileStream fs = null; Stream rs = null; try { string uploadFileName = new FileInfo(file).Name; string uploadUrl = ftpServer; DateTime startTime = DateTime.Now; Console.WriteLine("Start Time: {0}", startTime); long totalBytesSent = 0; // 统计已传输字节数 fs = new FileStream(file, FileMode.Open, FileAccess.Read); string ftpUrl = string.Format("{0}/{1}", uploadUrl, uploadFileName); FtpWebRequest requestObj = FtpWebRequest.Create(ftpUrl) as FtpWebRequest; requestObj.Method = WebRequestMethods.Ftp.UploadFile; rs = requestObj.GetRequestStream(); byte[] buffer = new byte[40960]; int read = 0; while ((read = fs.Read(buffer, 0, buffer.Length)) != 0) { rs.Write(buffer, 0, read); totalBytesSent += read; // 累加已传输字节数 } rs.Flush(); // 计算传输速率 DateTime endTime = DateTime.Now; TimeSpan elapsedTime = endTime - startTime; Console.WriteLine("End Time: {0}", endTime); if (elapsedTime.TotalSeconds > 0) { double bytesPerSecond = totalBytesSent / elapsedTime.TotalSeconds; double mbPerSecond = bytesPerSecond / (1024 * 1024); // 转换成MB/s Console.WriteLine($"Total Bytes Sent: {totalBytesSent:N0} bytes"); Console.WriteLine($"Elapsed Time: {elapsedTime.TotalSeconds:F2} seconds"); Console.WriteLine($"Transfer Rate: {mbPerSecond:F2} MB/s"); } else { Console.WriteLine("Transfer completed too quickly to calculate rate."); } } catch (Exception ex) { Console.WriteLine("File upload/transfer Failed.\r\nError Message:\r\n" + ex.Message); } finally { if (fs != null) { fs.Close(); fs.Dispose(); } if (rs != null) { rs.Close(); rs.Dispose(); } } Console.WriteLine("Exiting the application.. press any key to continue"); Console.ReadLine();
二、缓冲区大小调整提升速度的原理
这个优化的核心是减少IO操作的次数,降低系统开销,我用通俗的方式解释:
- 不管是从本地磁盘读文件(磁盘IO),还是往FTP服务器写数据(网络IO),每一次IO操作都有固定的"额外开销"——比如系统调用的上下文切换、网络请求的握手/分片处理等。
- 如果你的缓冲区很小(比如默认的4KB),你需要做成千上万次的读和写操作,每一次都要承担这些额外开销,累计下来会严重拖慢速度。
- 当你把缓冲区调到40960字节(也就是40KB),每次可以一次性读取和写入更多的数据,总的IO操作次数大幅减少,分摊到每个字节的额外开销就变得可以忽略,自然整体传输速度就提升了。
不过要注意:缓冲区不是越大越好。如果缓冲区过大,会占用过多的内存资源,甚至可能因为超过网络MTU(最大传输单元)导致数据被强制分片,反而增加额外开销。40KB是一个比较均衡的取值,既减少了IO次数,又不会带来其他副作用。
内容的提问来源于stack exchange,提问作者Tango
相关产品推荐
相关产品推荐

