2009-09-30 27 views
63

me encontré con el siguiente código en la web:manera confiable para convertir un archivo a un byte []

private byte [] StreamFile(string filename) 
{ 
    FileStream fs = new FileStream(filename, FileMode.Open,FileAccess.Read); 

    // Create a byte array of file stream length 
    byte[] ImageData = new byte[fs.Length]; 

    //Read block of bytes from stream into the byte array 
    fs.Read(ImageData,0,System.Convert.ToInt32(fs.Length)); 

    //Close the File Stream 
    fs.Close(); 
    return ImageData; //return the byte data 
} 

¿Es lo suficientemente confiable para utilizar para convertir un archivo de byte [] en C#, o hay una mejor manera de hacer esto?

+3

Debería poner 'fs.Close()' en la parte final de una declaración try-finally que encierra el resto del código, para asegurarse de que se llame 'Close'. – Joren

Respuesta

174
byte[] bytes = System.IO.File.ReadAllBytes(filename); 

Eso debería hacer el truco. ReadAllBytes abre el archivo, lee su contenido en una nueva matriz de bytes y luego lo cierra. Aquí está el MSDN page para ese método.

+0

¿Esto causaría un bloqueo de archivo? –

+0

Es decir, una vez que se completa el byte [], ¿no se seguirá bloqueando el archivo? –

+2

No, no lo haría, el archivo se cerrará tan pronto como se complete la matriz de bytes. –

3

parece lo suficientemente bueno como una versión genérica. Puede modificarlo para satisfacer sus necesidades, si son lo suficientemente específicas.

también prueba para las excepciones y condiciones de error, como el archivo no existe o no se puede leer, etc.

también puede hacer lo siguiente para ahorrar algo de espacio:

byte[] bytes = System.IO.File.ReadAllBytes(filename); 
21
byte[] bytes = File.ReadAllBytes(filename) 

o ...

+0

Downvoted para el uso ridículo de 'var' (solo explicando mi razón). –

+0

Vamos. De todos modos, lo cambiaré si te hace sentir mejor. –

+9

en serio? 'var' es perfectamente aceptable en este caso - el tipo de devolución está claramente indicado en el nombre del método ... –

2

Otros han señalado que puede utilizar el incorporado en File.ReadAllBytes. El método integrado está bien, pero vale la pena señalar que el código que publique anterior es frágil por dos razones:

  1. Stream es IDisposable - usted debe colocar la inicialización FileStream fs = new FileStream(filename, FileMode.Open,FileAccess.Read) en una cláusula de su uso para asegurar el archivo está cerrado . De lo contrario, la secuencia permanecerá abierta si se produce una falla, lo que significa que el archivo permanece bloqueado, lo que puede ocasionar otros problemas más adelante.
  2. fs.Read puede leer menos bytes de los que solicita. En general, el método .Read de una instancia Stream leerá al menos un byte, pero no necesariamente todos los bytes que solicite. Tendrá que escribir un bucle que vuelva a intentar leer hasta que se lean todos los bytes. This page explica esto con más detalle.
9

no repetir lo que todo el mundo ya han dicho, pero tenga presente lo siguiente handly la hoja de trucos para la manipulación de archivos:

  1. System.IO.File.ReadAllBytes(filename);
  2. File.Exists(filename)
  3. Path.Combine(folderName, resOfThePath);
  4. Path.GetFullPath(path); // converts a relative path to absolute one
  5. Path.GetExtension(path);
1

Todas estas respuestas con .ReadAllBytes().Otro, similar (no voy a decir duplicado, ya que estaban tratando de refactorizar su código) pregunta fue hecha en SO aquí: Best way to read a large file into a byte array in C#?

Se hizo un comentario sobre uno de los puestos con respecto .ReadAllBytes():

File.ReadAllBytes throws OutOfMemoryException with big files (tested with 630 MB file 
and it failed) – juanjo.arana Mar 13 '13 at 1:31 

Un mejor enfoque, para mí, sería algo como esto, con BinaryReader:

public static byte[] FileToByteArray(string fileName) 
{ 
    byte[] fileData = null; 

    using (FileStream fs = new File.OpenRead(fileName)) 
    { 
     var binaryReader = new BinaryReader(fs); 
     fileData = binaryReader.ReadBytes((int)fs.Length); 
    } 
    return fileData; 
} 

Pero así soy yo ...

Por supuesto, todo esto supone que tiene la memoria para manejar el byte[] una vez que se ha leído, y no puse el cheque File.Exists para asegurarse de que el archivo esté allí antes de continuar.