Stream.Length抛出NotSupportedException

Nev*_*hai 29 .net c# stream notsupportedexception

我在尝试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()
Run Code Online (Sandbox Code Playgroud)

你如何得到流的长度?任何例子?

Ree*_*sey 31

Stream.Length仅适用于可以进行搜索的Stream实现.您通常可以检查Stream.CanSeek是否为真.许多流,因为它们正在流式传输,其性质是不可能提前知道长度的.

如果您必须知道长度,则可能需要实际缓冲整个流,并提前将其加载到内存中.

  • 什么是关于`HttpClient.GetStreamAsync(url)`?它将设置Length-property但不可搜索.我是否必须使用try-catch测试Stream.Length属性的值? (5认同)

fro*_*rog 11

我在使用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. 
    }
Run Code Online (Sandbox Code Playgroud)


Pau*_*ett 9

这就是我做的:

    // 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;
    }
Run Code Online (Sandbox Code Playgroud)

  • 注意:如果文件大小可能超过2 GB(〜int.MaxValue),请对全字节读取类型使用长类型。 (2认同)

Jon*_*eet 6

您无法始终获得流的长度.例如,在网络流的情况下,找出长度的唯一方法是从中读取数据直到它被关闭.

你想做什么?您是否可以从流中读取,直到它耗尽,然后将数据复制到一个流程中MemoryStream

  • @Nevin:流还发生了什么?基本上,如果不通过阅读来改变状态,你将无法获得这些信息. (4认同)

dso*_*ano 6

如果它不支持搜索,则并不总是可以获得流的长度.请参阅Stream类的异常表.

例如,连接到另一个进程(网络流,标准输出等)的流可以产生任何数量的输出,具体取决于编写其他进程的方式,并且框架无法确定有多少数据.

在一般情况下,您只需读取所有数据,直到流结束,然后计算出您已读取了多少.