web-dev-qa-db-fra.com

Une manière élégante de consommer (tous les octets d'un) BinaryReader?

Existe-t-il un élégant pour imiter le StreamReader.ReadToEnd méthode avec BinaryReader? Peut-être pour mettre tous les octets dans un tableau d'octets?

Je fais ça:

read1.ReadBytes((int)read1.BaseStream.Length);

... mais il doit y avoir un meilleur moyen.

61
SamFisher83

Faites simplement:

byte[] allData = read1.ReadBytes(int.MaxValue);

Le documentation indique qu'il lira tous les octets jusqu'à la fin du flux.


Mise à jour

Bien que cela semble élégant et que la documentation semble indiquer que cela fonctionnerait, l'implémentation réelle (vérifiée dans .NET 2, 3.5 et 4) alloue un tableau d'octets de taille normale pour les données, ce qui provoquera probablement un OutOfMemoryException sur un système 32 bits.

Par conséquent, je dirais qu'en fait il n'y a pas de méthode élégante .

Au lieu de cela, je recommanderais la variation suivante de la réponse de @ iano. Cette variante ne repose pas sur .NET 4:
Créez une méthode d'extension pour BinaryReader (ou Stream, le code est le même pour les deux).

public static byte[] ReadAllBytes(this BinaryReader reader)
{
    const int bufferSize = 4096;
    using (var ms = new MemoryStream())
    {
        byte[] buffer = new byte[bufferSize];
        int count;
        while ((count = reader.Read(buffer, 0, buffer.Length)) != 0)
            ms.Write(buffer, 0, count);
        return ms.ToArray();
    }

}
90
Scott Rippey

Il n'y a pas de moyen facile de le faire avec BinaryReader. Si vous ne connaissez pas le décompte que vous devez lire à l'avance, il est préférable d'utiliser MemoryStream:

public byte[] ReadAllBytes(Stream stream)
{
    using (var ms = new MemoryStream())
    {
        stream.CopyTo(ms);
        return ms.ToArray();
    }
}

Pour éviter la copie supplémentaire lors de l'appel de ToArray(), vous pouvez à la place retourner le Position et le tampon, via GetBuffer().

69
iano

Pour copier le contenu d'un flux dans un autre, j'ai résolu la lecture de "certains" octets jusqu'à la fin du fichier:

private const int READ_BUFFER_SIZE = 1024;
using (BinaryReader reader = new BinaryReader(responseStream))
{
    using (BinaryWriter writer = new BinaryWriter(File.Open(localPath, FileMode.Create)))
    {
        int byteRead = 0;
        do
        {
            byte[] buffer = reader.ReadBytes(READ_BUFFER_SIZE);
            byteRead = buffer.Length;
            writer.Write(buffer);
            byteTransfered += byteRead;
        } while (byteRead == READ_BUFFER_SIZE);                        
    }                
}
3
Seraphim's