2009-09-30 5 views
63

J'ai trouvé le code suivant sur le web:manière fiable pour convertir un fichier à un octet []

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 
} 

Est-il assez fiable à utiliser pour convertir un fichier à octet [] dans C#, ou est-il une meilleure façon de le faire?

+3

Vous devriez mettre 'fs.Close()' dans la partie finale d'une instruction try-finally qui entoure le reste du code, pour s'assurer que 'Close' est réellement appelé. – Joren

Répondre

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

Cela devrait faire l'affaire. ReadAllBytes ouvre le fichier, lit son contenu dans un nouveau tableau d'octets, puis le ferme. Voici le MSDN page pour cette méthode.

+0

Est-ce que cela causerait un verrouillage de fichier? –

+0

Je veux dire - une fois l'octet [] rempli, le fichier ne sera-t-il pas encore verrouillé? –

+2

Non, ce n'est pas le cas - le fichier est fermé dès que le tableau d'octets est rempli. –

3

semble assez bon comme une version générique. Vous pouvez le modifier pour répondre à vos besoins, s'ils sont suffisamment spécifiques.

tester aussi des exceptions et des conditions d'erreur, tels que le fichier n'existe pas ou ne peut pas être lu, etc.

vous pouvez également effectuer les opérations suivantes pour économiser un peu d'espace:

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

ou ...

+0

Downvoted pour une utilisation ridicule de 'var' (juste pour expliquer ma raison). –

+0

Allez. De toute façon, je vais le changer si ça te fait te sentir mieux. –

+9

Sérieusement? 'var' est parfaitement acceptable dans ce cas - le type de retour est clairement indiqué dans le nom de la méthode ... –

2

D'autres ont noté que vous pouvez utiliser le haut-File.ReadAllBytes. La méthode intégrée est très bien, mais il est intéressant de noter que le code que vous postez ci-dessus est fragile pour deux raisons:

  1. Stream est-IDisposable - vous devez placer l'initialisation FileStream fs = new FileStream(filename, FileMode.Open,FileAccess.Read) dans une clause à l'aide que le fichier est fermé . Si vous ne le faites pas, cela peut signifier que le flux reste ouvert en cas de défaillance, ce qui signifie que le fichier reste verrouillé, ce qui peut causer d'autres problèmes plus tard.
  2. fs.Read peut lire moins d'octets que vous demandez. En général, la méthode .Read d'une instance Stream lit au moins un octet, mais pas nécessairement tous les octets demandés. Vous devrez écrire une boucle qui retente la lecture jusqu'à ce que tous les octets soient lus. This page explique cela plus en détail.
9

ne pas répéter ce que tout le monde a déjà dit, mais garder le handly antisèche suivant pour les manipulations de fichiers:

  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

Toutes ces réponses avec .ReadAllBytes().Un autre, similaire (je ne dirai pas en double, car ils essayaient de factoriser leur code) question a été posée sur le SO ici: Best way to read a large file into a byte array in C#?

Un commentaire a été fait sur l'un des messages concernant .ReadAllBytes():

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

Une meilleure approche, pour moi, serait quelque chose comme ça, avec 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; 
} 

Mais c'est juste moi ...

Bien sûr, tout ceci suppose que vous avez la mémoire pour gérer le byte[] une fois qu'il est lu, et je n'ai pas mis dans le File.Exists vérifier pour s'assurer que le fichier est là avant de continuer.

Questions connexes