c# - Stream.Length lanza la excepción NotSupportedException
.net (6)
Encontré este mismo problema al usar los servicios WCF. Necesitaba obtener el contenido de un mensaje POST, y estaba usando un argumento Stream en mi método para obtener el contenido del cuerpo del mensaje. Una vez que obtuve el flujo, quise leer todos sus contenidos a la vez, y necesitaba saber qué tamaño de matriz de bytes necesitaría. Por lo tanto, en la asignación de la matriz, llamaría a System.IO.Stream.Length y obtendría la excepción mencionada por el OP. ¿Es la razón por la que necesita saber la longitud del flujo para que pueda leer el contenido de todo el flujo? En realidad, puede leer todo el contenido del flujo en una cadena usando System.IO.StreamReader. Si aún necesita saber el tamaño de su transmisión, puede obtener la longitud de la cadena resultante. Aquí está el código de cómo resolví este problema:
[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.
}
Recibo un error al intentar transmitir. Duración en un objeto de Transmisión enviado a mi método WCF.
Unhandled Exception!
Error ID: 0
Error Code: Unknown
Is Warning: False
Type: System.NotSupportedException
Stack: at System.ServiceModel.Dispatcher.StreamFormatter.MessageBodyStream.get_Length()
¿Cómo se obtiene la longitud de la corriente? Algún ejemplo?
Esto es lo que hago:
// 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;
}
No siempre es posible obtener la longitud de un flujo si no admite la búsqueda. Consulte la tabla de excepciones en la Stream.Length .
Por ejemplo, un flujo conectado a otro proceso (flujo de red, salida estándar, etc.) puede producir cualquier cantidad de salida, dependiendo de cómo se escriba el otro proceso, y no hay forma de que el marco de trabajo determine cuántos datos hay .
En el caso general, solo tiene que leer todos los datos hasta el final de la secuencia y luego averiguar cuánto ha leído.
No siempre se puede obtener la longitud de una secuencia. En el caso de un flujo de red, la única forma de averiguar la longitud es leer los datos hasta que se cierre, por ejemplo.
¿Que estás tratando de hacer? ¿Podría leer de la transmisión hasta que se agote, copiando los datos en un MemoryStream
medida que MemoryStream
?
TcpClient.EndRead () debe devolver el número de bytes que están en la secuencia.
--Editar, por supuesto que necesitas estar usando una transmisión TCP
Stream.Length solo funciona en implementaciones de Stream donde está disponible la búsqueda. Por lo general, puede verificar si Stream.CanSeek es verdadero. Muchas corrientes, dado que se están transmitiendo , son de una naturaleza en la que es imposible saber la longitud de antemano.
Si debe conocer la longitud, es posible que necesite realmente almacenar en búfer el flujo completo, cargándolo en la memoria de antemano.