从基本流(httpRequestStream)读取

发布于 2024-12-27 05:51:19 字数 1382 浏览 0 评论 0原文

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

var s=new HttpListener().GetContext().Request.InputStream;

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

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

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

但由于它具有非字符内容,我们无法使用 StremReader (我尝试了所有编码机制..使用字符串是错误的)。而且我无法使用该函数,

context.Request.InputStream.Read(buffer,position,Len) 

因为我无法获取流的长度,InputStream.Length 总是抛出一个异常并且无法使用..并且我不想创建像[size][file]这样的小协议并读取第一个大小,然后读取文件...不知何故StreamReader可以获取长度..我只是想知道如何。 我也尝试过这个,但没有用,

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();
}

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

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();

谢谢乔恩,道格拉斯

I have a basic stream which is the stream of HTTP request
and

var s=new HttpListener().GetContext().Request.InputStream;

I want to read the stream (which contain non-Character content, because i've sent the packet)

When we wrap this stream by StreamReader then we use the ReadToEnd() function of StreamReader it can read the whole stream and return a string...

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

but since it has nonCharacter content we cant use StremReader (i tried all encoding mechanisms..using string is just wrong).And i Cant use the function

context.Request.InputStream.Read(buffer,position,Len) 

because I cant get the length of the stream, InputStream.Length always throws an exception and cant be used..and i dont want to create a small protocol like [size][file] and read first size then the file ...somehow the StreamReader can get the length ..and i just want to know how .
I also tried this and it didn't work

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();
}

I've solved it by the following

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();

thanks Jon , Douglas

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

断爱 2025-01-03 05:51:19

您的错误在于以下行:

byte b = (byte)ss.ReadByte();

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

对代码的快速修复:

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 内部实现的方式):

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);

Your bug lies in the following line:

byte b = (byte)ss.ReadByte();

The byte type is unsigned; when Stream.ReadByte returns -1 at the end of the stream, you’re indiscriminately casting it to byte, which converts it to 255 and, therefore, satisfies the b >= 0 condition. It is helpful to note that the return type is int, not byte, for this very reason.

A quick-and-dirty fix for your code:

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();
}

The following solution is more efficient, since it avoids the byte-by-byte reads incurred by the ReadByte calls, and uses a dynamically-expanding byte array for Read calls instead (similar to the way that List<T> is internally implemented):

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);
阳光下的泡沫是彩色的 2025-01-03 05:51:19

StreamReader 也无法获取长度 - 似乎对于 Stream.Read。该参数指定将读取的最大字节数,它不需要(而且实际上不能)等于流中实际可用的字节数。您只需在循环中调用 Read 直到它返回 0,在这种情况下您就知道您已到达流的末尾。这一切都记录在 MSDN 上,而且 StreamReader 也正是这样做的。

StreamReader读取请求并获取到string也是没有问题的;字符串在 .NET 中是二进制安全的,因此您可以放心使用。问题在于如何理解字符串的内容,但我们无法真正讨论这一点,因为您没有提供任何相关信息。

StreamReader cannot get the length either -- it seems there's some confusion regarding the third parameter of Stream.Read. That parameter specifies the maximum number of bytes that will be read, which does not need (and really cannot) be equal to the number of bytes actually available in the stream. You just call Read in a loop until it returns 0, in which case you know you have reached the end of the stream. This is all documented on MSDN, and it's also exactly how StreamReader does it.

There's also no problem in reading the request with StreamReader and getting it into string; strings are binary safe in .NET, so you 're covered. The problem will be making sense of the contents of the string, but we can't really talk about that since you don't provide any relevant information.

梦罢 2025-01-03 05:51:19

HttpRequestStream 不会为您提供长度,但您可以从 HttpListenerRequest.ContentLength64 属性获取它。正如 Jon 所说,请确保观察 Read 方法的返回值。就我而言,我们得到缓冲读取,并且无法一次性读取整个 226KB 有效负载。

尝试

    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;
    }

HttpRequestStream won't give you the length, but you can get it from the HttpListenerRequest.ContentLength64 property. Like Jon said, make sure you observe the return value from the Read method. In my case, we get buffered reads and cannot read our entire 226KB payload in one go.

Try

    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;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文