我正在调用一个写入流的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,那么我就不会试图实现它。
如果有人能给我展示一个如何实现抽象流类的抽象方法的非常基本的例子,我将不胜感激。
最简单的自定义流是"包装"其他流(类似于压缩流)的流。每个方法都会简单地将其实现重定向到内部流。
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。
如果您只想在调用Read、Seek或类似方法时激发事件,请重写基类版本,直接调用它们,并在之前或之后引发相应的事件。如果您想获得有关编写流类的帮助,请查看.Net代码本身,网址为http://referencesource.microsoft.com/netframework.aspx.但是,如果您想将流解析为更可读的内容,请考虑创建一个IEnumerable<MyClass>
来读取和处理流。