我正在调用写入流的dll。 dll中方法的签名如下:
public bool SomeMethod(Stream stream);
并且该方法基本上将二进制数据写入该流。所以,如果我将该方法称为:
var file = System.IO.File.Create("SomeFile.txt");
/* call dll method */ SomeMethod(file);
然后我将基本上将输出写入该文件。在这个问题中,我将输出写入networkStream。
无论如何回到问题。我想创建自己的流的原因是因为我想知道什么时候发生一些事件。例如,如果我在哪里创建自己的流类:
class MyStream : Stream
{
private long Position;
public override int Read(byte[] buffer, int offset, int count)
{
// implementation goes here
/* HERE I COULD CALL A CUSTOM EVENT */
}
public override long Seek(long offset, SeekOrigin origin)
{
// SAME THING I WILL LIKE TO PERFORM AN ACTION IF THIS METHOD IS CALLED!
}
// etc implement rest of abstract methods....
我正在将该流的输出写入网络,因此如果发生某些事件,我可能希望减速。如果我在哪里控制dll,那么我就不会尝试实现它。
如果有人能向我展示如何实现抽象Stream Class的抽象方法的一个非常基本的例子,我将不胜感激。
答案 0 :(得分:14)
最简单的自定义流“包装”其他流(类似于压缩流)。每种方法都只是将其实现重定向到内部流。
class MyStream : Stream
{
Stream inner;
public MyStream(Stream inner)
{
this.inner = inner;
}
public override int Read(byte[] buffer, int offset, int count)
{
var result = inner.Read(buffer, offset, count);
/* HERE I COULD CALL A CUSTOM EVENT */
return result;
}
///
}
使用示例:functionThatTakesStream(new MyStream(new MemoryStream());
。
真实代码需要在触发事件之前/之后处理内部流的操作中的异常并正确处理IDisposable。
答案 1 :(得分:1)
如果您要执行的操作是在调用Read,Seek或类似方法时触发事件,请覆盖基类版本,直接调用它们并在之前或之后引发相应的事件。如果您需要有关编写流类的帮助,请查看http://referencesource.microsoft.com/netframework.aspx处提供的.Net代码本身。但是,如果要将流解析为更具可读性的内容,请考虑创建一个读入并处理流的IEnumerable<MyClass>
。