2009-11-12 17 views
5

Supongamos que tenemos un bloque de código como este:de corriente leídos Problema

//Assuming s is a stream: 
byte[] data = new byte[1000]; 
s.Read(data,0,data.Length); 

el método Read podía leer en cualquier lugar de 1 a 1000 bytes, quedando el saldo de la corriente sin leer.

Esto es lo que dice un libro de C#.

No entiendo, ¿por qué Read método leería en cualquier lugar de la secuencia? No está leyendo toda la secuencia?

Y se dice que el trabajo en torno debe ser como este:

//bytesRead will always end up at 1000, unless the stream is itself smaller in length: 
int bytesRead = 0; 
int chunkSize = 1; 
while(bytesRead < data.Length && chunkSize > 0) 
     bytesRead += chunkSize = s.Read(data,bytesRead,dataLength-bytesRead); 

Este código también es proporcionada por el libro como una solución temporal. Lo que trato de entender es si el método Read está comenzando a leerse hasta el final y escribir todos los bytes en el rango especificado en byte array. ¿Por qué está utilizando el bytesRead como punto de partida en s.Read(data,bytesRead,dataLength-bytesRead);

Gracias de antemano.

Respuesta

8

La idea es que los datos pueden no estar disponibles al momento de llamar a Leer ... o nunca. Por ejemplo, en un NetworkStream, los datos pueden estar llegando más lentamente de lo que lo está recogiendo. O puede que esté cerca del final de un FileStream. Es posible que The Stream sepa que restan menos bytes de los que pidió, o puede que no tenga forma de saber cuándo llegará o no la cantidad completa de bytes solicitados. Por lo tanto, en lugar de esperar a que lleguen datos que posiblemente nunca lleguen o fallar con un error de "no hay suficientes bytes, adivine de nuevo", Read se reserva el derecho de devolver menos de lo que había solicitado.

En consecuencia, al leer un fragmento en una matriz de bytes, es posible que no esté llenando la matriz de bytes. Pero desea que el siguiente fragmento se anexe donde quedó el último, en lugar de sobrescribir el principio de la matriz de bytes. Por lo tanto, pasar bytesRead como la ubicación de inicio para colocar el siguiente fragmento en la matriz de bytes.

0

Basado en mi lectura de la documentación del método Read, porque las secuencias se pueden utilizar para leer fuentes de datos muy variables, desde entrada de teclado hasta archivos para el tráfico de red, se ha dejado abierta a la implementación específica si los datos devueltos por el método de lectura devolverá el número solicitado de bytes. Por ejemplo, si una implementación particular para leer datos de red desea devolver los 500 bytes de datos que están disponibles hasta ahora para una solicitud web, pero espera que no se realice hasta que se lean 1000 bytes, y ha solicitado 1000 bytes, puede devolver lo que tiene para que pueda procesarlo. Le dirá que solo lee 500 bytes, y debe tener en cuenta que puede haber más en el camino. El máximo de 1000 es solo una indicación de que no desea procesar más que 1000 bytes a la vez.

2

El primer ejemplo es usar el tamaño declarado 1000 de la matriz de bytes como un parámetro de entrada en el método Read.

El segundo ejemplo es leer la transmisión de un byte a la vez, lo cual es excelente para transmitir datos entrantes o salientes, lo que significa que si puede procesar porciones de la transmisión que está recibiendo sin almacenarla completamente en memoria esto es enfoque más eficiente.

Creo que lo que te confunde aquí es que el autor está limitando artificialmente el ejemplo a un máximo de 1,000 bytes.Una gran cantidad de protocolos que involucran la transmisión por lo general envían un byte o dos al principio, notificando específicamente al consumidor de la longitud de la transmisión como un todo para que pueda dividir y procesar mejor la transmisión, por lo que no se requiere un límite declarado de 1,000. Obtienes el tamaño, lo desmenuzas adecuadamente (incluido el último trozo, que puede no ser el tamaño completo del trozo) y procesas cada trozo.

+0

¿Quiere decir que primero envían el tamaño de los datos que desean enviar y luego envían los datos completos como fragmentos en lugar de enviarlos como un todo? – Tarik

+0

Normalmente sí. Supongamos que tiene un archivo de 40 MB en el disco que desea transferir. En lugar de cargar 40 MB en la memoria y luego transferirlo, lo que hace que 40 MB de memoria se acumulen durante un tiempo, simplemente lee, digamos los primeros 1024 bytes, transfiérala y continúe en fragmentos de 1024 bytes. Un protocolo de transferencia de archivos puede indicar que "los primeros dos bytes del primer paquete contienen un int sin signo que indica el tamaño de la carga útil" para que sepa cuándo dejar de leer ese flujo. El extremo receptor puede hacer lo mismo, dividirlo en 1024 bytes o algún otro número de buffer amigable con los recursos. – cfeduke

1

No entiendo, ¿por qué el método de lectura leerá en cualquier lugar de la secuencia? ¿No está leyendo toda la secuencia?

Lectura le permite especificar los puntos de inicio y final para la lectura. Ver la respuesta de itowlson para más información.

Lo que estoy tratando de entender si Leer método empieza a leer a final y escribir todos los bytes en rango especificado para el conjunto de bytes.

Si esta es una pregunta, supongo que la respuesta es no. El método Read rellena una matriz con datos de una secuencia en los puntos de inicio y finalización especificados.

¿Por qué usa los bytesRead como punto de inicio en s.Read (data, bytesRead, dataLength-bytesRead);

Él está usando bytesRead para realizar un seguimiento de "la cantidad de bytes leídos". Esto le permite saber por dónde empezar a leer en la próxima llamada de Lectura.

4

La frase "podría leer desde 1 hasta 1000 bytes" significa "podría leer 1 byte, o 2 bytes, hasta 1000 bytes". Se refiere a longitud de bytes leídos, no la ubicación. La lectura será ubicada en la posición actual de la secuencia.

Cuestiones relacionadas