0

我一直在尝试制作一个程序来将带宽限制的文件(压缩后)传输到同一网络上的另一台计算机。

我需要限制其带宽以避免饱和(Robocopy 的方式)。

最近,我找到了这个ThrottledStream类,但它似乎不起作用,因为我可以发送一个 9MB 限制为 1 字节限制的内容,它仍然几乎立即到达,所以我需要知道该类是否存在一些误用。

这是代码:

using (FileStream originStream = inFile.OpenRead())    
using (MemoryStream compressedFile = new MemoryStream())      
using (GZipStream zippingStream = new GZipStream(compressedFile, CompressionMode.Compress))
{
    originStream.CopyTo(zippingStream); 
    using (FileStream finalDestination = File.Create(destination.FullName + "\\" + inFile.Name + ".gz"))
    {
        ThrottledStream destinationStream = new ThrottledStream(finalDestination, bpsLimit);
        byte[] buffer = new byte[bufferSize];
        int readCount = compressedFile.Read(buffer,0,bufferSize);
        while(readCount > 0)
        {
            destinationStream.Write(buffer, 0, bufferSize);
            readCount = compressedFile.Read(buffer, 0, bufferSize);
        }
    }
}

任何帮助,将不胜感激。

4

1 回答 1

1

您链接到的ThrottledStream类使用延迟计算来确定在执行当前写入之前等待多长时间。此延迟基于当前写入之前发送的数据量,以及经过了多少时间。一旦延迟期过去,它将整个缓冲区写入单个块中。

这样做的问题是它不会对特定写入操作中写入的缓冲区大小进行任何检查。如果您要求它将吞吐量限制为每秒 1 个字节,然后Write使用 20MB 缓冲区调用该方法,它将立即写入整个 20MB。如果您随后尝试写入另一个 2 字节长的数据块,它将等待很长时间(20*2^20 秒),然后再写入这两个字节。

为了让ThrottledStream课程更顺利地工作,您必须Write使用非常小的数据块进行调用。每个块仍然会立即写入,但写入操作之间的延迟会更小,吞吐量会更均匀。

在您的代码中,您使用一个名为的变量bufferSize来确定内部循环中每次读/写要处理的字节数。尝试设置bufferSize为 256,这将导致更多的读取和写入,但将ThrottledStream有机会实际引入一些延迟。

如果您设置bufferSize为相同,bpsLimit您应该会看到每秒完成一个写入操作。您设置的越小,bufferSize每秒获得的写入操作越多,带宽限制就越平滑。

通常我们希望在每个操作中处理尽可能多的缓冲区以减少开销,但在这种情况下,您明确尝试添加开销以减慢速度:)

于 2013-06-07T00:34:09.310 回答