2016-10-25 6 views
5

別の質問では、GetResponseStream()を介してHttpWebResponseから読み取ると、人々は不完全なデータを取得しています。HttpWebResponseがデータを失うのはなぜですか?

この問題は、エンベデッドデバイスからデータを読み込む際に、すべての32バイトヘッダーと64バイト* 1000の1000入力の設定を送信する必要があります。その結果、64032バイトのデータが得られます。

レスポンスストリームを直接読み取ると、最初の61個の半分の入力のデータしか得られません。そこからのデータはゼロだけです。

バージョンA)動作していない:

int headerSize = 32; 
int inputSize = 64; 
byte[] buffer = new byte[(inputSize*1000) + headerSize]; 

HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

using (Stream stream = response.GetResponseStream()) 
{ 
    if (stream != null) 
    { 
     stream.Seek(0, SeekOrigin.Begin); 
     stream.Read(buffer, 0, buffer.Length); 
    } 
} 

response.Close(); 
return buffer; 

問題を可視化するために、私は別々に各入力構成のための64のバイトを印刷しました。基本的には、40個のASCII文字と、ブール値と整数値を表す数バイトから構成されます。

バージョンA)出力:

1/1000 | 46656E7374657220576F686E656E2020202020202020202020202020202020202020202020202020000000000F0EB0AA00008100000001800000100090010020 
2/1000 | 42574D20576F686E656E202020202020202020202020202020202020202020202020202020202020000000000F0EB0AA00008100000001800000100091010080 
… 
61/1000 | 53656E736F72203631202020202020202020202020202020202020202020202020202020202020200000000000000000000010003300000000001000C3010000 
62/1000 | 53656E736F7220363220202020202020202020202020202020202020202020200000000000000000000000000000000000000000000000000000000000000000 
63/1000 | 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 
… 
999/1000 | 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 
1000/1000 | 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 

私は新しいのMemoryStreamにResponseStreamをコピーすると、私は壊れバイトせずに完全にすべての1000の入力を読み取ることができます。完璧に仕事

バージョンB):

(また、最初のケースでは私の問題を修正https://stackoverflow.com/a/22354617/6290907を参照してください)

int headerSize = 32; 
int inputSize = 64; 
byte[] buffer = new byte[(inputSize*1000) + headerSize]; 

HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

using (Stream stream = response.GetResponseStream()) 
{ 
    if (stream != null) 
    { 
     MemoryStream memStream = new MemoryStream(); 
     stream.CopyTo(memStream); 
     memStream.Flush(); 
     stream.Close(); 

     memStream.Seek(0, SeekOrigin.Begin); 
     memStream.Read(buffer, 0, buffer.Length); 

     memStream.Close(); 
    } 
} 

response.Close(); 
return buffer; 

バージョンB)技術から出力

1/1000 | 46656E7374657220576F686E656E2020202020202020202020202020202020202020202020202020000000000F0EB0AA00008100000001800000100090010020 
2/1000 | 42574D20576F686E656E202020202020202020202020202020202020202020202020202020202020000000000F0EB0AA00008100000001800000100091010080 
… 
61/1000 | 53656E736F72203631202020202020202020202020202020202020202020202020202020202020200000000000000000000010003300000000001000C3010000 
62/1000 | 53656E736F72203632202020202020202020202020202020202020202020202020202020202020200000000000000000000010003300000000001000C3010000 
63/1000 | 53656E736F72203633202020202020202020202020202020202020202020202020202020202020200000000000000000000010003300000000001000C3010000 
… 
999/1000 | 53656E736F7220393939202020202020202020202020202020202020202020202020202020202020000000000000000000001000DA030000000010006A050000 
1000/1000 | 53656E736F7220313030302020202020202020202020202020202020202020202020202020202020000000000000000000001000DB030000000010006B050000 

視点:HttpWebResponseが直接アクセスするとデータを失うのはなぜですか? 私はただ動作させるだけではありませんが、なぜバージョンaが失敗し、バージョンbが成功したのか、両方が同じデータソース(response.GetResponseStream())に依存しているかを理解したいと思います。 このケースでは何が起こっていますか?

ありがとうございました!

答えて

2

docsによって記載されているようにintは、Stream.Readによって返さ調べる:

そのバイト数 が現在利用できない、またはゼロ(0)であれば場合、これは要求されたバイトの数より少なくすることができますストリームの最後に に達しました。

私は最初の呼び出しでストリームの一部だけが返されることを喜んで賭けています。

Stream.Readを繰り返し呼び出すと、最後にすべてのバイトが得られます。 httpストリームは、あなたのコードが実行されているよりもゆっくりと読み込まれています。Readに電話する前に完了するための時間がありません。

MemoryStreamCopyToを使用すると、コール全体がストリームが読み取られるまでブロックされます。StreamReaderで折り返し、ReadToEndを呼び出すと同じ結果が得られます。

+0

int bytesRead = 0; int bytesToRead = buffer.Length; do { int n = s.Read(buffer、bytesRead、bytesToRead); bytesRead + = n; bytesToRead - = n; } while(bytesToRead!= 0); –

+0

それはトリックでした!私は組み込みの世界ではかなり新しいので、以前はテキストで作業していたので、テキストベースのStreamReaderを使用していないときに読み込まれたバイト数を見逃してしまいました。 ありがとうございました! –

+0

@ManuelR:あなたは大歓迎です! – Baldrick

関連する問題