我在尝试stream.Length发送到我的WCF方法的Stream对象时遇到错误。
Unhandled Exception!
Error ID: 0
Error Code: Unknown
Is Warning: False
Type: System.NotSupportedException
Stack: at System.ServiceModel.Dispatcher.StreamFormatter.MessageBodyStream.get_Length()
你如何获得流的长度?任何例子?
答案 0 :(得分:30)
Stream.Length仅适用于可以进行搜索的Stream实现。您通常可以查看Stream.CanSeek是否为真。许多流,因为它们正在流式传输,其性质是不可能事先知道长度的。
如果你必须知道长度,你可能需要实际缓冲整个流,提前将其加载到内存中。
答案 1 :(得分:10)
使用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.
}
答案 2 :(得分:7)
这就是我的所作所为:
// 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;
}
答案 3 :(得分:6)
您无法始终获得流的长度。例如,在网络流的情况下,找出长度的唯一方法是从中读取数据,直到它关闭为止。
你想做什么?您是否可以从流中读取,直到它耗尽,然后将数据复制到MemoryStream
?
答案 4 :(得分:6)
如果不支持搜索,则无法始终获得流的长度。请参阅Stream class上的例外表。
例如,连接到另一个进程(网络流,标准输出等)的流可以产生任何数量的输出,具体取决于编写其他进程的方式,并且框架无法计算出多少有数据。
在一般情况下,您只需读取所有数据,直到流结束,然后计算出您已阅读的数量。
答案 5 :(得分:0)
TcpClient.EndRead()应该返回流中的字节数。
- 编辑,当然你需要使用TCP流