如何模拟慢速和无读取缓存磁盘驱动器

时间:2013-07-28 06:47:19

标签: .net wpf windows disk

我需要检查我的Windows应用程序,看看它在具有慢速磁盘的系统上是如何工作的。 我怎么能有一个模拟的慢速磁盘,Windows不会缓存它的内容,所以我可以重复我的测试?

更新:我有很多代码访问磁盘,无法创建用于模拟慢速光盘的新类,部分代码是第三方和无法访问源代码。

更新2:我也需要降低Directory.GetFiles()的速度。

4 个答案:

答案 0 :(得分:2)

您可以创建慢decorator而不是Stream,这会延迟执行一些(或全部)操作:

public class SlowStream : Stream
{
    private Stream _stream;
    private TimeSpan _delay;

    public SlowStream(Stream stream, TimeSpan delay)
    {
        _stream = stream;
        _delay = delay;
    }

    // implementation
}

实现流成员时,您应该将一些操作直接委托给装饰流

public override bool CanRead 
{
    get { return _stream.CanRead; }
}

public override void Flush() 
{
    _stream.Flush();
}

public override void Close() 
{
    _stream.Close();
}

但是在你希望变慢的其他操作之前做延迟:

public void Wait() 
{
    Thread.Sleep(_delay);
}

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

public override void Write(byte[] buffer, int offset, int count)
{
    Wait();
    _stream.Write(buffer, offset, count);
}    

用法:

using(var stream = File.Open(fileName, FileMode.Open))
{
    var slowStream = new SlowStream(stream, TimeSpan.FromSeconds(1));
    var reader = new StreamReader(slowStream);
    string line;
    while((line = reader.ReadLine()) != null)
        Console.WriteLine(line);
}

答案 1 :(得分:1)

您可以使用虚拟机并限制磁盘访问...以下是有关如何在Virtualbox 5.8中进行操作的一些提示。限制磁盘映像的带宽https://www.virtualbox.org/manual/ch05.html#storage-bandwidth-limit

我认为MS和VMWare虚拟化工具提供了类似的功能。

答案 2 :(得分:0)

如果您有源代码,您可以编写一个模拟磁盘行为的类,并通过调用您的类来替换所有磁盘读/写代码。

您需要缓存应用程序完成的请求,并在延迟一段时间后执行它们。

如果您无法访问代码,那么您希望找到一个模拟慢速磁盘的驱动程序......如果有这样的话。

答案 3 :(得分:0)

感谢谢尔盖的答案,但是在某些情况下,它可以用更少的代码完成而没有装饰器 - 只需继承所需的Stream对象并用延迟覆盖Read方法。以下是类似情况下足以满足我需求的示例类:

    public class SlowStream : MemoryStream
    {
        private readonly TimeSpan _delay;

        public SlowStream(byte[] buffer, TimeSpan delay)
            : base(buffer)
        {
            _delay = delay;
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            Thread.Sleep(_delay);
            return base.Read(buffer, offset, count);
        }
    }