2012-01-22 7 views

Respuesta

9

Si su escenario le permite reemplazar su secuencia original, entonces puede verificar si admite búsqueda y, si no, leer su contenido y envolverlos en un nuevo MemoryStream, que luego podría usar para las operaciones posteriores.

static string PeekStream(ref Stream stream) 
{ 
    string content; 
    var reader = new StreamReader(stream); 
    content = reader.ReadToEnd(); 

    if (stream.CanSeek) 
    { 
     stream.Seek(0, SeekOrigin.Begin); 
    } 
    else 
    { 
     stream.Dispose(); 
     stream = new MemoryStream(Encoding.UTF8.GetBytes(content)); 
    } 

    return content; 
} 

Lo anterior es bastante ineficiente, ya que debe asignar memoria para dos veces el tamaño de su contenido. Mi recomendación sería adaptar las partes de su código a las que está accediendo a la transmisión (después de haber leído todo su contenido) para hacer que accedan a la copia almacenada de su contenido. Por ejemplo:

string content; 
using (var reader = new StreamReader(stream)) 
    content = reader.ReadToEnd(); 

// Process content here. 

string line; 
using (var reader = new StringReader(content)) 
    while ((line = reader.ReadLine()) != null) 
     Console.WriteLine(line); 

Desde el StringReader simplemente lee de la cadena de content, usted no perder la memoria creación de copias repetidas de sus datos.

+0

Este enfoque es correcto hasta que tenga datos muy grandes. Si tiene algunos gigabytes, es mejor reiniciar su transmisión. En mi opinión, el propósito de la transmisión es no almacenar todos los datos que está procesando. –

+0

Tiene razón acerca de 'MemoryStream' no es adecuado para grandes cantidades de datos. Ya sea para almacenar o reiniciar la transmisión depende del escenario. Por ejemplo, si está procesando datos descargados de Internet y necesita leerlos varias veces, entonces es mejor almacenar los datos localmente (en la memoria o en un archivo temporal) que descargarlos nuevamente. – Douglas

5

Utilice otra implementación de Stream que admita la búsqueda. Si Stream.CanSeek devuelve falso, entonces esa implementación está afirmando que no es compatible con la búsqueda.

El objeto MemoryStream es compatible con la búsqueda. Puede copiar una secuencia arbitraria en un MemoryStream usando algo como esto, y la secuencia resultante admitirá la búsqueda, por ejemplo, puede restablecer la posición a 0 y leer de ella repetidamente.

MemoryStream CopyStreamToMemory(Stream inputStream) 
{ 
    MemoryStream ret = new MemoryStream(); 
    const int BUFFER_SIZE = 1024; 
    byte[] buf = new byte[BUFFER_SIZE]; 

    int bytesread = 0; 
    while ((bytesread = inputStream.Read(buf, 0, BUFFER_SIZE)) > 0) 
     ret.Write(buf, 0, bytesread); 

    ret.Position = 0; 
    return ret; 
} 

Por supuesto, si su flujo lee los datos que no cambia, sólo tiene que desechar el antiguo arroyo, y crear una nueva corriente que lee los mismos datos.

Cuestiones relacionadas