¿La mejor manera de leer un archivo grande en una matriz de bytes en C#?
Tengo un servidor web que leerá archivos binarios grandes (varios megabytes) en matrices de bytes. El servidor podría estar leyendo varios archivos al mismo tiempo (diferentes solicitudes de página), por lo que estoy buscando la forma más optimizada de hacerlo sin sobrecargar demasiado la CPU. ¿El siguiente código es lo suficientemente bueno?
public byte[] FileToByteArray(string fileName)
{
byte[] buff = null;
FileStream fs = new FileStream(fileName,
FileMode.Open,
FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
long numBytes = new FileInfo(fileName).Length;
buff = br.ReadBytes((int) numBytes);
return buff;
}
Simplemente reemplace todo con:
return File.ReadAllBytes(fileName);
Sin embargo, si le preocupa el consumo de memoria, no debe leer todo el archivo en la memoria de una sola vez. Deberías hacerlo en trozos.
Podría argumentar que la respuesta aquí generalmente es "no". A menos que necesite absolutamente todos los datos a la vez, considere usar una Stream
API basada en (o alguna variante de lector/iterador). Esto es especialmente importante cuando tiene múltiples operaciones paralelas (como lo sugiere la pregunta) para minimizar la carga del sistema y maximizar el rendimiento.
Por ejemplo, si está transmitiendo datos a una persona que llama:
Stream dest = ...
using(Stream source = File.OpenRead(path)) {
byte[] buffer = new byte[2048];
int bytesRead;
while((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) {
dest.Write(buffer, 0, bytesRead);
}
}
Yo pensaría esto:
byte[] file = System.IO.File.ReadAllBytes(fileName);
Su código se puede factorizar con esto (en lugar de File.ReadAllBytes):
public byte[] ReadAllBytes(string fileName)
{
byte[] buffer = null;
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int)fs.Length);
}
return buffer;
}
Tenga en cuenta la limitación de tamaño de archivo Integer.MaxValue impuesta por el método de lectura. En otras palabras, sólo puedes leer un fragmento de 2 GB a la vez.
Tenga en cuenta también que el último argumento de FileStream es el tamaño del búfer.
También sugeriría leer sobre FileStream y BufferedStream .
Como siempre, un programa de muestra simple para perfilar cuál es el más rápido será el más beneficioso.
Además, su hardware subyacente tendrá un gran efecto en el rendimiento. ¿Está utilizando unidades de disco duro basadas en servidor con cachés grandes y una tarjeta RAID con memoria caché integrada? ¿O estás utilizando una unidad estándar conectada al puerto IDE?