从基本流(httpRequestStream)读取
我有一个基本流,它是 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的错误在于以下行:
byte
类型是无符号的;当Stream.ReadByte
返回 -1 时在流的末尾,您不加区别地将其转换为byte
,这会将其转换为 255,因此满足b >= 0
条件。正是由于这个原因,请注意返回类型是int
,而不是byte
。对代码的快速修复:
以下解决方案更加高效,因为它避免了由
ReadByte
调用引起的逐字节读取,并使用动态扩展的字节数组来进行读取。相反,Read
调用(类似于List
内部实现的方式):Your bug lies in the following line:
The
byte
type is unsigned; whenStream.ReadByte
returns -1 at the end of the stream, you’re indiscriminately casting it tobyte
, which converts it to 255 and, therefore, satisfies theb >= 0
condition. It is helpful to note that the return type isint
, notbyte
, for this very reason.A quick-and-dirty fix for your code:
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 forRead
calls instead (similar to the way thatList<T>
is internally implemented):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 ofStream.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 callRead
in a loop until it returns0
, in which case you know you have reached the end of the stream. This is all documented on MSDN, and it's also exactly howStreamReader
does it.There's also no problem in reading the request with
StreamReader
and getting it intostring
; 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.HttpRequestStream
不会为您提供长度,但您可以从HttpListenerRequest.ContentLength64
属性获取它。正如 Jon 所说,请确保观察 Read 方法的返回值。就我而言,我们得到缓冲读取,并且无法一次性读取整个 226KB 有效负载。尝试
HttpRequestStream
won't give you the length, but you can get it from theHttpListenerRequest.ContentLength64
property. Like Jon said, make sure you observe the return value from theRead
method. In my case, we get buffered reads and cannot read our entire 226KB payload in one go.Try