example - file.readallbytes c#




La meilleure façon de lire un gros fichier dans un tableau d'octets en C#? (6)

Il suffit de remplacer le tout avec:

return File.ReadAllBytes(fileName);

Cependant, si vous êtes préoccupé par la consommation de mémoire, vous ne devriez pas lire tout le fichier en mémoire en une seule fois. Vous devriez le faire en morceaux.

J'ai un serveur Web qui lira de gros fichiers binaires (plusieurs mégaoctets) dans des tableaux d'octets. Le serveur pourrait lire plusieurs fichiers en même temps (demandes de pages différentes), donc je suis à la recherche de la manière la plus optimisée de le faire sans trop taxer le CPU. Le code ci-dessous est-il assez bon?

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;
}

Je dirais que BinaryReader est bien, mais peut être refactorisé à ceci, au lieu de toutes ces lignes de code pour obtenir la longueur du tampon:

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

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

Devrait être mieux que d'utiliser .ReadAllBytes() , puisque j'ai vu dans les commentaires sur la réponse supérieure qui inclut .ReadAllBytes() que l'un des commentateurs avait des problèmes avec les fichiers> 600 Mo, car un BinaryReader est destiné à ce genre de chose. En outre, le placer dans une instruction using garantit que FileStream et BinaryReader sont fermés et éliminés.


Je pourrais faire valoir que la réponse ici est généralement "ne pas". À moins d' avoir absolument besoin de toutes les données à la fois, pensez à utiliser une API basée sur les Stream (ou une variante de lecteur / itérateur). Ceci est particulièrement important lorsque vous avez plusieurs opérations en parallèle (comme suggéré par la question) pour minimiser la charge du système et maximiser le débit.

Par exemple, si vous diffusez des données à un appelant:

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);
    }
}

Je recommanderais d'essayer la méthode Response.TransferFile() puis un Response.Flush() et Response.End() pour servir vos fichiers volumineux.


Si vous avez affaire à des fichiers de plus de 2 Go, vous trouverez que les méthodes ci-dessus échouent.

Il est beaucoup plus facile de transférer le flux à MD5 et de le partager avec vous:

private byte[] computeFileHash(string filename)
{
    MD5 md5 = MD5.Create();
    using (FileStream fs = new FileStream(filename, FileMode.Open))
    {
        byte[] hash = md5.ComputeHash(fs);
        return hash;
    }
}

Utilisez la classe BufferedStream en C # pour améliorer les performances. Un tampon est un bloc d'octets en mémoire utilisé pour mettre en cache des données, réduisant ainsi le nombre d'appels au système d'exploitation. Les tampons améliorent les performances de lecture et d'écriture.

Voir ce qui suit pour un exemple de code et une explication supplémentaire: BufferedStream







binary-data