2012-01-15 7 views
5

から、私はHTTPリクエスト と読むには基本的な流れ(httpRequestStream)

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を使用するカント文字以外のコンテンツを持っているので、(私はすべてのエンコーディングmechanisms..using文字列がちょうど間違ってみました).AND私は、ストリーム、InputStreamの長さを取得カントので、私は機能

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

を使用カント.Lengthは常に例外をスローし、使用することはできません。そして、[サイズ] [ファイル]のような小さなプロトコルを作成して、最初のサイズのファイルを読み込みたくありません。何とかStreamReaderで長さを取得できます。方法を知りたいダグラス

、 は私もこれを試してみましたが、それは私が次

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

おかげジョンことによってそれを解決してきました

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

動作しませんでした

+0

を試してみてください。 2つのヒント: (1)FileStreamを自動的に閉じるために 'using'ステートメントを使用する方法を学びます。 (2)大量のbyte []バッファは必要ありません。なぜなら、1回のRead呼び出しで大量のデータを読み込むことはまずないからです。おそらく約8192のサイズで十分でしょう。 – Douglas

答えて

6

あなたのバグは、次の行にある:

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

byteタイプが符号なしです。 Stream.ReadByteがストリームの最後に-1を返すと、それをbyteに無差別にキャストします。これは255に変換され、したがってb >= 0の条件を満たします。このため、戻り値のタイプはbyteではなく、intであることに注意してください。

あなたのコードのための間に合わせおよびフィックス:

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呼び出しによって被っ読み取り回避するので、より効率的であり、かつdynamically-を使用しています(List<T>が内部的に実装される方法に類似)の代わりにReadコールのためにバイト配列を拡大:

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

Lol、私はちょうどあなたのコメントを見た。情報の感謝...しかし、私は2番目の配列としてファイルを使用します..so私は配列のサイズを変更する必要はありません – CnativeFreak

5

StreamReader長さを得ることができないのいずれか - それをStream.Readの3番目のパラメータに関する混乱があるようです。このパラメータは、最大でのバイト数を指定します。これは、ストリームで実際に使用可能なバイト数を必要とせず、実際には使用できません。 0を返すまで、ループの中でReadを呼び出すだけで、ストリームの終わりに達していることがわかります。これはMSDNですべて文書化されており、それも正確にStreamReaderの処理方法です。

StreamReaderでリクエストを読み、それをstringにすることに問題はありません。文字列は.NETではバイナリセーフなので、カバーされています。問題は文字列の内容を理解することになりますが、関連する情報を提供していないので、実際にはそれについて話すことはできません。

+0

True ..私はそれほど説明しませんでした。lenが私に言いたいのは、すでに作成されたバイトです。[] b =新しいバイト[len]ですが、このlenは取得できません。文字列に関する私の問題は、バイトから文字列へのエンコードとその逆のエンコーディングですが、エンコードのステップではいつも私のバイトが乱されます.. – CnativeFreak

+0

そして、私はtriend var = new StreamReader(context.Request.InputStream、Encoding.ASCII);そして、UnicodeとUTF8は、 "新しいAsciiEncoding()。GetBytes(str)"を使用して、スクラムリングされたバイトを得ました。 – CnativeFreak

+0

とReadByte関数はストリームの最後に-1を返します..無限ループを得ました.. – CnativeFreak

0

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; 
    } 
関連する問題