WCFメソッドに送信されたStreamオブジェクトでstream.Lengthを試行すると、エラーが発生します。
Unhandled Exception!
Error ID: 0
Error Code: Unknown
Is Warning: False
Type: System.NotSupportedException
Stack: at System.ServiceModel.Dispatcher.StreamFormatter.MessageBodyStream.get_Length()
ストリームの長さをどのように取得しますか?何か例は?
Stream.Length は、シークが可能なStream実装でのみ機能します。通常、 Stream.CanSeek がtrueかどうかを確認できます。多くのストリームはstreamedであるため、事前に長さを知ることは不可能です。
長さを知る必要がある場合は、実際にストリーム全体をバッファリングして、事前にメモリにロードする必要がある場合があります。
WCFサービスを使用しているときにも同じ問題が発生しました。 POSTメッセージのコンテンツを取得する必要があり、メッセージの本文のコンテンツを取得するためにメソッドでStream引数を使用していました。ストリームを取得したら、そのコンテンツを読みたいと思いました一度に、どのサイズのバイト配列が必要かを知る必要がありました。そのため、配列の割り当てでは、System.IO.Stream.Lengthを呼び出して、OPによって示された例外を取得します。ストリームの長さを知っているので、ストリーム全体のコンテンツを読み取ることができますか?System.IO.StreamReaderを使用して、ストリームのコンテンツ全体を文字列に実際に読み取ることができます。ストリームのサイズを知る必要がある場合は、結果の文字列の長さを取得できますこの問題を解決するためのコードは次のとおりです。
[OperationContract]
[WebInvoke(UriTemplate = "authorization")]
public Stream authorization(Stream body)
{
// Obtain the token from the body
StreamReader bodyReader = new StreamReader(body);
string bodyString= bodyReader.ReadToEnd();
int length=bodyString.Length; // (If you still need this.)
// Do whatever you want to do with the body contents here.
}
これが私がすることです:
// Return the length of a stream that does not have a usable Length property
public static long GetStreamLength(Stream stream)
{
long originalPosition = 0;
long totalBytesRead = 0;
if (stream.CanSeek)
{
originalPosition = stream.Position;
stream.Position = 0;
}
try
{
byte[] readBuffer = new byte[4096];
int bytesRead;
while ((bytesRead = stream.Read(readBuffer, 0, 4096)) > 0)
{
totalBytesRead += bytesRead;
}
}
finally
{
if (stream.CanSeek)
{
stream.Position = originalPosition;
}
}
return totalBytesRead;
}
常にストリームの長さを取得できるわけではありません。ネットワークストリームの場合、長さを確認する唯一の方法は、たとえばデータが閉じられるまでそこからデータを読み取ることです。
あなたは何をしようとしているのですか?ストリームがなくなるまでストリームから読み取り、データをMemoryStream
にコピーしますか?
シークをサポートしていない場合、ストリームの長さを取得できるとは限りません。 ストリームクラス の例外表を参照してください。
たとえば、他のプロセス(ネットワークストリーム、標準出力など)に接続されたストリームは、他のプロセスの記述方法に応じて、任意の量の出力を生成できます。フレームワークがデータの量を把握する方法はありません。 。
一般的なケースでは、ストリームの終わりまですべてのデータを読み取って、どれだけ読み取ったかを把握する必要があります。
TcpClient.EndRead()は、ストリーム内のバイト数を返す必要があります。
-編集、もちろん、TCP Streamを使用する必要があります