Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我的Inject方法不将数据注入流?_C#_Stream - Fatal编程技术网

C# 为什么我的Inject方法不将数据注入流?

C# 为什么我的Inject方法不将数据注入流?,c#,stream,C#,Stream,我已经为C#流编写了一个包装类,因为我希望它能够将数据注入流,并在通过ReadAsync()读取数据时调用函数。然而,“注入”部分不起作用,我不知道为什么 class ExtendedStream : Stream { private readonly Stream _originalStream; private readonly Action<byte[]> _readCallback; private ManualResetEvent dataInje

我已经为C#
编写了一个包装类,因为我希望它能够将数据注入流,并在通过ReadAsync()读取数据时调用函数。然而,“注入”部分不起作用,我不知道为什么

class ExtendedStream : Stream
{
    private readonly Stream _originalStream;
    private readonly Action<byte[]> _readCallback;

    private ManualResetEvent dataInjected = new ManualResetEvent(false);
    private List<byte> data = new List<byte>();
    private int pos = 0;

    public ExtendedStream(Stream originalStream, Action<byte[]> readCallback)
    {
        _originalStream = originalStream;
        _readCallback = readCallback;
    }

    public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken)
    {
        var read = await _originalStream.ReadAsync(buffer, offset, count, cancellationToken);

        _readCallback(buffer);

        return read;
    }

    public void Inject(string text)
    {
        data.AddRange(new UTF8Encoding(false).GetBytes(text));
        dataInjected.Set();
    }

    private IEnumerable<byte> GetBytes(int count)
    {
        int returned = 0;

        while (returned == 0)
        {
            if (pos < data.Count)
            {
                while (pos < data.Count && returned < count)
                {
                    yield return data[pos];

                    pos += 1; returned += 1;
                }
            }
            else
            {
                dataInjected.Reset();
                dataInjected.WaitOne();
            }
        }
    }       

    public override int Read(byte[] buffer, int offset, int count)
    {
        var bytes = GetBytes(count).ToArray();

        for (int i = 0; offset + i < buffer.Length && i < bytes.Length; i++)
        {
            buffer[offset + i] = bytes[i];
        }

        return bytes.Length;
    }

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

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

    public override bool CanSeek
    {
        get { return _originalStream.CanSeek; }
    }

    public override bool CanWrite
    {
        get { return _originalStream.CanWrite; }
    }

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

    public override long Length
    {
        get { return _originalStream.Length; }
    }

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

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

    public override void SetLength(long value)
    {
        _originalStream.SetLength(value);
    }        
}
类扩展流:流
{
私有只读流_originalStream;
私有只读操作_readCallback;
private ManualResetEvent dataInjected=新的ManualResetEvent(错误);
私有列表数据=新列表();
私人int pos=0;
public ExtendedStream(Stream originalStream,Action readCallback)
{
_原始流=原始流;
_readCallback=readCallback;
}
公共重写异步任务ReadAsync(字节[]缓冲区、整数偏移量、整数计数、System.Threading.CancellationToken CancellationToken)
{
var read=await_originalStream.ReadAsync(缓冲区、偏移量、计数、取消令牌);
_读取回调(缓冲区);
返回读取;
}
公共void注入(字符串文本)
{
data.AddRange(新的UTF8Encoding(false).GetBytes(text));
dataInjected.Set();
}
私有IEnumerable GetBytes(整数计数)
{
返回的int=0;
while(返回==0)
{
如果(位置<数据计数)
{
while(pos
然后我用XmlReader读取流,如下所示

using (XmlReader xmlReader = XmlReader.Create(_extendedStream, new XmlReaderSettings() { Async = true }))
{
                while (await xmlReader.ReadAsync())
                {                        
                    switch (xmlReader.NodeType)
                    {                            
                        case XmlNodeType.EndElement:
                            if (xmlReader.LocalName.Equals("test"))
                            {
                                _log.Debug("</test> injected!");                            
                            }
                            break;
                        default:                              
                            break;
                    }
}
使用(XmlReader=XmlReader.Create(_extendedStream,new XmlReaderSettings(){Async=true}))
{
while(等待xmlReader.ReadAsync())
{                        
开关(xmlReader.NodeType)
{                            
案例XmlNodeType.EndElement:
if(xmlReader.LocalName.Equals(“test”))
{
_调试(“注入!”);
}
打破
违约:
打破
}
}

如果我调用
\u extendedStream.Inject(“”
),数据永远不会被注入。有人知道为什么吗?

您的
ReadAsync
方法委托给
\u originalStream.ReadAsync
,因此我认为您的被重写的
Read
方法(注入魔法发生的地方)从未在示例代码中被调用过

您可以将原始流的读取移动到
read
方法中,而不是重写
ReadAsync
(这可能会变得复杂),基本
ReadAsync
方法将异步调用该方法

// UNTESTED CODE, MAY CONTAIN OFF BY ONE ERRORS
public override int Read(byte[] buffer, int offset, int count)
{
    int totalBytesRead = 0;
    var bytes = GetBytes(count).ToArray();

    // write injected bytes into buffer
    for (int i = 0; offset + i < buffer.Length && i < bytes.Length; i++)
    {
        buffer[offset + i] = bytes[i];
    }

    if(bytes.Length < count)
    {
        // we reached the end of the custom bytes, so read the rest from the original stream
        count = count - bytes.Length;
        offset += bytes.Length;
        totalBytesRead = _originalStream.Read(buffer, offset, count);
    }

    totalBytesRead += bytes.Length;

    _readCallback(buffer);

    return totalBytesRead;
}
//未测试的代码,可能包含一个接一个的错误
公共重写整型读取(字节[]缓冲区、整型偏移量、整型计数)
{
int totalBytesRead=0;
var bytes=GetBytes(count).ToArray();
//将注入的字节写入缓冲区
对于(int i=0;偏移量+i

这可能需要一些调整,以防止注入的数据被反复注入,但至少注入逻辑将运行。

您的
ReadAsync
方法将委托给
\u originalStream.ReadAsync
,因此我不认为您被重写的
Read
方法(注入魔法发生的地方)是否在示例代码中被调用过。您是否尝试过使用调试器进行单步调试?嗯……是的,我确实使用调试器检查了代码。我认为(不要问我为什么),
ReadAsync
使用了
Read
,就像在中的示例中建议的那样。我如何覆盖
ReadAsync
(示例将是超级的)?