Stream.CopyTo - 如何获取发送的字节?

2024-02-15


我尝试获取 ftp 上传的传输速度,但我不知道应该在哪里“获取”它:

代码片段:

FtpWebRequest request = (FtpWebRequest)WebRequest.Create(job.GetDestinationFolder() + "\\" + fileOnlyName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(Manager._user, Manager._password);

using (var requestStream = request.GetRequestStream())
{
     using (var input = File.OpenRead(file))
     {
          //input.CopyToAsync()
          input.CopyTo(requestStream);
          //IS HERE ANY METHOD OR ATTRIBUTE, WHICH SHOWS THE SENT BYTES ?
     }
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();
}

我已经读过这段代码 https://stackoverflow.com/a/230141/109702

public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[32768];
    int read;
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write (buffer, 0, read);
    }
}

根据评论 https://stackoverflow.com/questions/230128/how-do-i-copy-the-contents-of-one-stream-to-another#comment1560483_230141剩下的:

请注意,这不是最快的方法。在提供的代码片段中,您必须等待写入完成才能读取新块。当异步执行读取和写入时,这种等待将消失。在某些情况下,这将使复制速度提高两倍。然而,这会使代码变得更加复杂,因此如果速度不是问题,请保持简单并使用这个简单的循环。

如何显示像在 chrome 或 firefox 上下载一样的传输速度?


EDIT:
This is what I tried before you (Tien Dinh) answered:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(job.GetDestinationFolder() + "\\" + fileOnlyName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(Manager._user, Manager._password);

using (var requestStream = request.GetRequestStream())
{
    using (var input = File.OpenRead(file))
    {
        Console.WriteLine(input.Length);//bGroundWorker.ReportProgress(request.)
        Console.WriteLine(input.Position);
        while (input.Position != input.Length)
        {
            input.CopyToAsync(requestStream);
            Console.WriteLine(input.Position);
            //bGroundWorker.ReportProgress( (int) input.Position);
        }
        Console.WriteLine(input.Length + "(length)");
        Console.WriteLine(input.Position + "(sent)");
        //e.Result = input.Position;
    }
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();

正如您所看到的,有一个BackgroundWorker,因此我使用CopyToAsync。


您可以构建自己的流包装类来报告在定义的时间间隔内写入的字节数:

public class StreamWithProgress : Stream
{
    private readonly TimeSpan interval;
    private readonly long sourceLength;
    private readonly Stopwatch stopwatch = Stopwatch.StartNew();
    private readonly BackgroundWorker worker;

    private int bytesInLastInterval;
    private long bytesTotal;
    private Stream innerStream;

    public override bool CanRead
    {
        get { return this.innerStream.CanRead; }
    }

    public override bool CanSeek
    {
        get { return this.innerStream.CanSeek; }
    }

    public override bool CanWrite
    {
        get { return this.innerStream.CanWrite; }
    }

    public override long Length
    {
        get { return this.innerStream.Length; }
    }

    public override long Position
    {
        get { return this.innerStream.Position; }
        set { this.innerStream.Position = value; }
    }

    public StreamWithProgress(Stream stream, BackgroundWorker worker, long sourceLength, TimeSpan? interval = null)
    {
        if (stream == null)
        {
            throw new ArgumentNullException("stream");
        }

        if (worker == null)
        {
            throw new ArgumentNullException("worker");
        }

        this.interval = interval ?? TimeSpan.FromSeconds(1);
        this.innerStream = stream;
        this.worker = worker;
        this.sourceLength = sourceLength;
    }

    public override void Flush()
    {
        this.innerStream.Flush();
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return this.innerStream.Read(buffer, offset, count);
    }

    public override int ReadByte()
    {
        return this.innerStream.ReadByte();
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return this.innerStream.Seek(offset, origin);
    }

    public override void SetLength(long value)
    {
        this.innerStream.SetLength(value);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        this.innerStream.Write(buffer, offset, count);
        this.ReportProgress(count);
    }

    public override void WriteByte(byte value)
    {
        this.innerStream.WriteByte(value);
        this.ReportProgress(1);
    }

    protected override void Dispose(bool disposing)
    {
        if (this.innerStream != null)
        {
            this.innerStream.Dispose();
            this.innerStream = null;
        }
    }

    private void ReportProgress(int count)
    {
        this.bytesInLastInterval += count;
        this.bytesTotal += count;

        if (this.stopwatch.Elapsed > this.interval)
        {
            double speed = this.bytesInLastInterval / (this.stopwatch.Elapsed.Ticks / (double) this.interval.Ticks);
            double progress = this.bytesTotal / (double) this.sourceLength;
            var progressPercentage = (int) (progress * 100);

            this.worker.ReportProgress(progressPercentage, speed);

            this.bytesInLastInterval = 0;
            this.stopwatch.Restart();
        }
    }
}

你可以像这样使用它:

BackgroundWorker worker = (BackgroundWorker)sender;
WebRequest request = WebRequest.Create("SOME URL");
WebResponse response = request.GetResponse();

using (Stream stream = response.GetResponseStream())
using (var dest = new StreamWithProgress(File.OpenWrite("PATH"), worker, response.ContentLength))
{
    stream.CopyTo(dest);
}

将以当前进度和速度重复调用BackgroundWorker。您可以使用存储最后 n 个速度并报告平均值的队列来优化该示例。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Stream.CopyTo - 如何获取发送的字节? 的相关文章

  • 金特 + XNA (C#)

    是否可以使用jint http jint codeplex com操作使用 XNA C 创建的 3D 环境 并向该环境添加功能 再次使用 jint 作为 Jint 的贡献者 我会推荐你Jint http jint codeplex com
  • Volatile.Read 和 Volatile.Write 背后的逻辑是什么?

    来自 MSDN Volatile Read 读取字段的值 在需要它的系统上 插入一个 阻止处理器重新排序内存的内存屏障 操作如下 如果在该方法之后出现读或写 代码 处理器无法移动它before这个方法 and Volatile Write
  • 如何使用 ASP.NET MVC 编辑多选列表?

    我想编辑一个如下所示的对象 我希望用 UsersGrossList 中的一个或多个用户填充 UsersSelectedList 使用 mvc 中的标准编辑视图 我只得到映射的字符串和布尔值 下面未显示 我在 google 上找到的许多示例都
  • 我如何知道 C 程序的可执行文件是在前台还是后台运行?

    在我的 C 程序中 我想知道我的可执行文件是否像这样在前台运行 a out 或者像这样 a out 如果你是前台工作 getpgrp tcgetpgrp STDOUT FILENO or STDIN FILENO or STDERR FIL
  • 进程退出后 POSIX 名称信号量不会释放

    我正在尝试使用 POSIX 命名信号量进行跨进程同步 我注意到进程死亡或退出后 信号量仍然被系统打开 在进程 打开它 死亡或退出后是否有办法使其关闭 释放 早期的讨论在这里 当将信号量递减至零的进程崩溃时 如何恢复信号量 https sta
  • MFC CList 支持复制分配吗?

    我在 MSVC 中查找了 CList 定义afxtempl h http www cppdoc com example mfc classdoc MFC AFXTEMPL H html并记录在MSDN http msdn microsoft
  • 司机和提供商之间的区别

    数据库中的驱动程序和提供程序有什么区别 有没有解释一下 不胜感激 样本 ADO NET driver for MySQL vs providerName System Data EntityClient 来自 MSDN 论坛 驱动程序是安装
  • 在 ASP.NET MVC 中将模型从视图传递到控制器

    我正在 ASP NET MVC 中开发我的第一个应用程序 但遇到了一个我无法解决的问题 即使在阅读了整个互联网之后也是如此 因此 我有几个使用视图模型创建的视图 它们是报告 这些视图模型是根据用户选择标准填充的 我正在尝试构建一种接受模型并
  • C# 编译器数字文字

    有谁知道 C 编译器数字文字修饰符的完整列表 默认情况下 声明 0 使其成为 Int32 声明 0 0 使其成为 Double 我可以在末尾使用文字修饰符 f 来确保某些内容被视为 Single 例如像这样 var x 0 x is Int
  • 有什么方法可以重载 C# 中的扩展方法吗?

    我有以下模型模式 public abstract class PARENTCLASS public class CHILD A CLASS PARENTCLASS public static class EXTENSION public s
  • 如何在win32中使用GetSaveFileName保存文件?

    我编写此代码是为了获取 fileName 来保存我的文件 include stdafx h include
  • 如何使用递归查找数字中的最小元素 [C]

    好的 所以我正在准备我的 C 考试 当谈到递归时我有点卡住了我是大学一年级的学生 这对我来说似乎有点困难 练习要求在给定的数字中使用递归函数我需要找到最小的元素 例如 52873 是 2 程序需要打印 2 include
  • Resharper:IEnumerable 的可能多重枚举

    我正在使用新的 Resharper 版本 6 在我的代码中的几个地方 它给一些文本加了下划线 并警告我可能存在IEnumerable 可能的多重枚举 我理解这意味着什么 并在适当的情况下采纳了建议 但在某些情况下 我不确定这实际上是一个大问
  • 使用 OleDbCommandBuilder 时访问 SQL 语法错误

    我要在 C 中使用 OleDbDataAdapter 在 Access 数据库中插入数据 但收到错误消息INSERT INTO 命令中的语法错误 BackgroundWorker worker new BackgroundWorker Ol
  • EnumDisplayDevices 与 WMI Win32_DesktopMonitor,如何检测活动监视器?

    对于我当前的 C 项目 我需要为在大量计算机上连接并处于活动状态的每个监视器检测一个唯一的字符串 研究指出了两种选择 使用 WMI 并查询 Win32 DesktopMonitor 以获取所有活动监视器 使用 PNPDeviceID 来唯一
  • 无法在 C# 中为 EventArgs 分配使用派生类型的事件处理程序

    所以我有一个事件声明如下 public event EventHandler OnChangeDetected 然后我有以下处理程序被分配给该事件 myObject OnChangeDetected OnTableChanged 我的理解是
  • C 语言中的 Alpha 混合 2 RGBA 颜色[重复]

    这个问题在这里已经有答案了 可能的重复 如何快速进行阿尔法混合 https stackoverflow com questions 1102692 how to do alpha blend fast 对 2 个 RGBA 整数 颜色进行
  • 如何将 int 作为“void *”传递给线程启动函数?

    我最初有一个用于斐波那契变量数组的全局变量 但发现这是不允许的 我需要进行基本的多线程处理并处理竞争条件 但我无法在 pthread 创建中将 int 作为 void 参数提供 我尝试过使用常量指针 但没有成功 由于某些奇怪的原因 void
  • printf或iostream如何指定点后的最大位数

    字符串采用什么格式printf or iomanip我应该使用 iostream 中的运算符以以下格式打印浮点数 125 0 gt 125 125 1 gt 125 1 125 12312 gt 125 12 1 12345 gt 1 12
  • SQL Server“未找到网络路径”在不同环境中随机且不频繁地发生

    类似 如果不是同一个问题 随机遇到网络路径未找到异常 https stackoverflow com questions 38696448 network path not found exception encountered rando

随机推荐