2009-02-26 8 views
5

Ejemplo:¿Las secuencias de .NET ahorran memoria?

  1. Si leo un archivo y copiarlo a otro archivo a través de .NET corrientes será el tamaño total del archivo de ocupar la memoria en cualquier momento? ¿O los bytes se descartarán tan pronto como se utilicen?
  2. Si el enfoque ingenuo no ahorra memoria sería amortiguado Las corrientes lo hacen?
+0

¡Buena pregunta! :) – overslacked

Respuesta

13

Si transmite su copia, es decir, lee un búfer, escribe un búfer, lee un búfer, escribe un búfer, etc. hasta que se le acaben los datos, solo necesitará tanta memoria como el tamaño del búfer. Espero que File.Copy haga esto (en el código nativo de Windows).

Si desea hacerlo usted mismo, usar algo como esto:

public void CopyData(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[32 * 1024]; 
    int read; 
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write(buffer, 0, read); 
    } 
} 

Esto sólo se llevará a 32K por grande que la corriente es.

EDITAR: Como se señala en los comentarios, las transmisiones también pueden tener sus propios búferes, pero el punto es que aún se puede transferir un archivo muy grande sin quedarse sin memoria.

+0

... + el tamaño de cualquier búfer interno utilizado por el flujo (FileStream usa un búfer interno cuyo tamaño predeterminado es 4K) – Joe

+0

.NET FileStreams tienen sus propios búferes internos. Entonces, usar el código anterior con FileStreams probablemente lleva algo más de 32K de memoria (32K + cualquiera que sea el tamaño del buffer interno de FileStream). Pero en cualquier caso, se usa una cantidad constante de memoria con esta técnica. –

+0

Buenos puntos, ambos. Actualizando ... –

3

Si llama algo así como ReadToEnd(), entonces sí, el contenido del archivo se cargará en la memoria. Tiene razón al adivinar que utilizar un búfer es el enfoque adecuado para garantizar que solo un subconjunto de los datos del archivo se cargue en la memoria en un momento dado.

2

No, el archivo completo no se cargará en la memoria.

La huella de memoria dependerá del tamaño de los búferes que utilice para leer y escribir, y de cualquier búfer interno mantenido por la secuencia.

La clase FileStream utiliza un búfer interno cuyo tamaño se puede especificar en una sobrecarga de constructor y cuyo valor predeterminado es 0x1000 bytes (probablemente depende de la implementación; este valor se obtuvo examinando la clase FileStream utilizando Lutz Reflector).

1

Realmente depende de su metodología. Si está utilizando la transmisión como un punto final temporal con ReadToEnd(), puede cargar todo el archivo en la memoria. Si, en cambio, está almacenando en búfer, no usará más que un poco de sobrecarga en el tamaño del búfer.

+0

Nota breve: ReadToEnd() existe en TextReader, no en Stream. –

Cuestiones relacionadas