C# 为什么StreamReader.ReadToEnd有效,而Stream.Read无效?

C# 为什么StreamReader.ReadToEnd有效,而Stream.Read无效?,c#,asp.net-core,.net-core,C#,Asp.net Core,.net Core,我试图在ASP.NET核心控制器中以字节[]数组的形式获取请求主体。以下是我最初写的: var declaredLength = (int)request.ContentLength; byte[] fileBuffer = new byte[declaredLength]; request.Body.Read(fileBuffer, 0, declaredLength); 此代码可以工作,但仅适用于小请求(约20KB)。对于较大的请求,它将填充数组中大约20000个字节,然后数组的其余部分

我试图在ASP.NET核心控制器中以
字节[]
数组的形式获取请求主体。以下是我最初写的:

var declaredLength = (int)request.ContentLength;
byte[] fileBuffer = new byte[declaredLength];

request.Body.Read(fileBuffer, 0, declaredLength);
此代码可以工作,但仅适用于小请求(约20KB)。对于较大的请求,它将填充数组中大约20000个字节,然后数组的其余部分为空

我在顶部答案中使用了一些代码,在重写代码后,我成功地读取了整个请求正文:

var declaredLength = (int)request.ContentLength;
byte[] fileBuffer = new byte[declaredLength];

// need to enable, otherwise Seek() fails
request.EnableRewind();

// using StreamReader apparently resolves the issue
using (var reader = new StreamReader(request.Body, Encoding.UTF8, true, 1024, true))
{
    reader.ReadToEnd();
}

request.Body.Seek(0, SeekOrigin.Begin);
request.Body.Read(fileBuffer, 0, declaredLength);

为什么
StreamReader.ReadToEnd()
能够成功读取整个请求正文,而
Stream.read()
不能?两次读取请求流感觉像是一种黑客行为。有没有更好的办法?(我只需要将流读入字节数组一次)

请记住,在收到所有请求之前,您正在尝试读取
request.Body

行为如下:

  • 如果已到达流的末尾,则返回
    0
  • 如果没有尚未读取的可用字节,则阻塞,直到至少有1个字节可用
  • 如果有1个或多个新字节可用,请立即返回它们。不要堵住
  • 如您所见,如果尚未收到整个正文,
    request.body.Read(…)
    将只返回已收到的正文部分

    StreamReader.ReadToEnd()
    调用
    Stream.Read
    ,直到找到流的结尾

    您可能应该在循环中调用
    Stream.Read
    ,直到您读取了所有字节:

    byte[] fileBuffer = new byte[declaredLength];
    int numBytesRead = 0;
    while (numBytesRead < declaredLength)
    {
        int readBytes = request.Body.Read(fileBuffer, numBytesRead, declaredLength - numBytesRead);
        if (readBytes == 0)
        {
            // We reached the end of the stream before we were expecting it
            // Might want to throw an exception here?
        }
        numBytesRead += readBytes;
    }
    
    byte[]fileBuffer=新字节[declaredLength];
    int numBytesRead=0;
    while(numBytesRead
    StreamReader使用Windows文件系统方法,当达到EOF时关闭流,而流在远端未关闭。您一定要考虑切换到。