首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从基本流(httpRequestStream)读取

从基本流(httpRequestStream)读取
EN

Stack Overflow用户
提问于 2012-01-15 21:48:06
回答 3查看 8.3K关注 0票数 5

我有一个基本流,它是HTTP请求的流,

代码语言:javascript
复制
var s=new HttpListener().GetContext().Request.InputStream;

我想要读取流(它包含非字符内容,因为我已经发送了数据包)

当我们用StreamReader包装这个流时,然后我们使用StreamReader的ReadToEnd()函数,它可以读取整个流并返回一个字符串...

代码语言:javascript
复制
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://127.0.0.1/");
listener.Start();
var context = listener.GetContext();
var sr = new StreamReader(context.Request.InputStream);
string x=sr.ReadToEnd(); //This Workds

但是因为它有nonCharacter内容,所以我们不能使用StremReader (我尝试了所有的编码mechanisms..using字符串都是错误的).And我不能使用函数

代码语言:javascript
复制
context.Request.InputStream.Read(buffer,position,Len) 

因为我不能得到流的长度,InputStream.Length总是抛出一个异常,不能是used..and,我不想创建一个小的协议,比如size,然后读取第一个大小,然后文件...somehow StreamReader就可以得到长度..and,我只想知道是怎么回事。我也试过了,但不起作用

代码语言:javascript
复制
List<byte> bb = new List<byte>();
var ss = context.Request.InputStream;
byte b = (byte)ss.ReadByte();
while (b >= 0)
{
    bb.Add(b);
    b = (byte)ss.ReadByte();
}

我已经通过以下方法解决了这个问题

代码语言:javascript
复制
FileStream fs = new FileStream("C:\\cygwin\\home\\Dff.rar", FileMode.Create);
byte[] file = new byte[1024 * 1024];
int finishedBytes = ss.Read(file, 0, file.Length);
while (finishedBytes > 0)
{
    fs.Write(file, 0, finishedBytes);
    finishedBytes = ss.Read(file, 0, file.Length);
}
fs.Close();

谢谢乔恩,道格拉斯

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-15 22:03:45

您的bug存在于以下代码行中:

代码语言:javascript
复制
byte b = (byte)ss.ReadByte();

byte类型是无符号的;当Stream.ReadByte在流的末尾返回-1时,您将不加区别地将其转换为byte,后者将其转换为255,因此满足b >= 0条件。需要注意的是,由于这个原因,返回类型是int,而不是byte

对您的代码进行快速修复:

代码语言:javascript
复制
List<byte> bb = new List<byte>();
var ss = context.Request.InputStream;
int next = ss.ReadByte();
while (next != -1)
{
    bb.Add((byte)next);
    next = ss.ReadByte();
}

下面的解决方案效率更高,因为它避免了ReadByte调用引起的逐字节读取,而是对Read调用使用动态扩展的字节数组(类似于List<T>在内部实现的方式):

代码语言:javascript
复制
var ss = context.Request.InputStream;

byte[] buffer = new byte[1024];
int totalCount = 0;

while (true)
{
    int currentCount = ss.Read(buffer, totalCount, buffer.Length - totalCount);
    if (currentCount == 0)
        break;

    totalCount += currentCount;
    if (totalCount == buffer.Length)
        Array.Resize(ref buffer, buffer.Length * 2);
}

Array.Resize(ref buffer, totalCount);
票数 6
EN

Stack Overflow用户

发布于 2012-01-15 21:54:05

StreamReader也无法获得长度--似乎对Stream.Read的第三个参数有一些混淆。该参数指定将读取的最大字节数,它不需要(也确实不能)等于流中实际可用的字节数。您只需在循环中调用Read,直到它返回0,在这种情况下,您知道您已经到达了流的末尾。所有这些都记录在MSDN上,这也正是StreamReader如何做到这一点。

使用StreamReader读取请求并将其放入string中也没有问题;字符串在.NET中是二进制安全的,因此您将了解字符串的内容。问题将是理解字符串的内容,但我们不能真正讨论这一点,因为您没有提供任何相关信息。

票数 5
EN

Stack Overflow用户

发布于 2016-12-09 08:12:01

HttpRequestStream不会给出长度,但是可以从HttpListenerRequest.ContentLength64属性中获得。正如Jon所说,确保观察Read方法的返回值。在我的例子中,我们得到了缓冲读取,并且不能一次性读取整个226KB的有效负载。

试一试

代码语言:javascript
复制
    byte[] getPayload(HttpListenerContext context)
    {
        int length = (int)context.Request.ContentLength64;
        byte[] payload = new byte[length];
        int numRead = 0;
        while (numRead < length)
            numRead += context.Request.InputStream.Read(payload, numRead, length - numRead);

        return payload;
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8870101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档