gpt4 book ai didi

c# - 为什么 StreamReader.ReadToEnd 有效但 Stream.Read 无效?

转载 作者:行者123 更新时间:2023-11-30 22:52:05 26 4
gpt4 key购买 nike

我正在尝试将 ASP.NET Core Controller 中的请求正文作为 byte[] 数组获取。这是我最初写的:

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

request.Body.Read(fileBuffer, 0, declaredLength);

此代码有效,但仅适用于小请求(大约 20KB)。对于较大的请求,它会填满数组中的前 20,000 个字节左右,然后数组的其余部分为空。

我在顶部答案中使用了一些代码 here ,并且在重写我的代码后能够成功读取整个请求体:

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()却不能?两次读取请求流感觉就像一个 hack。有没有更好的方法来解决这个问题? (我只需要将流读入字节数组一次)

最佳答案

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

Stream.Read行为如下:

  1. 如果到达流的末尾,返回0
  2. 如果没有尚未读取的可用字节,则阻塞直到至少有 1 个字节可用
  3. 如果有 1 个或多个新字节可用,则立即返回它们。不要阻止。

如您所见,如果尚未收到整个正文,request.Body.Read(...) 将只返回已收到的正文部分。

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

您可能还应该在循环中调用 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;
}

关于c# - 为什么 StreamReader.ReadToEnd 有效但 Stream.Read 无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58523944/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com