2010-10-25 18 views
25

Ceci est un simple, et un que je pensais avoir été répondu. J'ai essayé de trouver une réponse ici, mais je n'ai rien trouvé - alors je m'excuse si quelque chose m'a manqué.Equivalent de StringBuilder pour les tableaux d'octets

Quoi qu'il en soit, existe-t-il un équivalent de StringBuilder mais pour les tableaux d'octets? Je ne suis pas dérangé par toutes les différentes surcharges de Append() - mais j'aimerais voir Append(byte) et Append(byte[]).

Y a-t-il quelque chose autour de vous ou est-ce que c'est du temps libre?

Répondre

25

Would MemoryStream travail pour vous? L'interface n'est peut-être pas aussi pratique, mais elle offre un moyen simple d'ajouter des octets, et lorsque vous avez terminé, vous pouvez obtenir le contenu en appelant ToArray().

Un StringBuilder-like interface pourrait probablement être réalisé en faisant une méthode d'extension.

Mise à jour
Les méthodes d'extension pourraient ressembler à ceci:

public static class MemoryStreamExtensions 
{ 
    public static void Append(this MemoryStream stream, byte value) 
    { 
     stream.Append(new[] { value }); 
    } 

    public static void Append(this MemoryStream stream, byte[] values) 
    { 
     stream.Write(values, 0, values.Length); 
    } 
} 

Utilisation:

MemoryStream stream = new MemoryStream(); 
stream.Append(67); 
stream.Append(new byte[] { 68, 69 }); 
byte[] data = stream.ToArray(); // gets an array with bytes 67, 68 and 69 
+0

Oui, il serait - j'aime cette approche ... Merci –

+0

Puis-je demander - je n'ai pas vu la syntaxe 'new [] {value}' avant - est-ce inférer le type du tableau? –

+2

@Matt: oui, c'est correct. Dans la méthode d'extension, 'value' est de type' byte', donc 'byte []' est déduit. Dans le dernier exemple, je dois spécifier 'new byte []' car le compilateur déduirait le type 'int' dans le cas contraire. –

11

Probablement List<byte>:

var byteList = new List<byte>(); 
byteList.Add(42); 
byteList.AddRange(new byte[] { 1, 2, 3 }); 
+0

... puis Append (octet) devient Ajouter (octet) et Append (octet []) devient AddRange (octet []). –

+0

Notez que comme avec 'StringBuilder', l'ajout d'éléments à' List' est amorti O (1). – Brian

+0

Ok, cool - juste une question ... Serait-ce aussi efficace? Je sais que List <> fait des copies efficaces pour AddRange sous le capot, mais je ne savais pas si cela fonctionnait comme le moyen le plus efficace de le faire? –

2

List<byte> Ensuite, quand vous le voulez comme un tableau que vous pouvez appeler ToArray()

12

Le MemoryStream approche est bon, mais si vous voulez avoir un comportement similaire à StringBuilder, ajoutez un BinaryWriter. BinaryWriter fournit toutes les substitutions d'écriture que vous pourriez vouloir.

MemoryStream stream = new MemoryStream(); 
BinaryWriter writer = new BinaryWriter(stream); 
writer.Write((byte)67); 
writer.Write(new byte[] { 68, 69 }); 
+0

+1 Bonne solution! – kol

+0

Vous pouvez également dériver une nouvelle classe de BinaryWriter si vous avez besoin d'écrivains spéciaux. J'ai fait un qui a manipulé des conversions de hton. –

0
using System; 
using System.IO; 

public static class MemoryStreams 
{ 
    public static MemoryStream Append(
     this MemoryStream stream 
     , byte value 
     , out bool done) 
    { 
     try 
     { 
      stream.WriteByte(value); 
      done = true; 
     } 
     catch { done = false; } 
     return stream; 
    } 

    public static MemoryStream Append(
     this MemoryStream stream 
     , byte[] value 
     , out bool done 
     , uint offset = 0 
     , Nullable<uint> count = null) 
    { 
     try 
     { 
      var rLenth = (uint)((value == null) ? 0 : value.Length); 

      var rOffset = unchecked((int)(offset & 0x7FFFFFFF)); 

      var rCount = unchecked((int)((count ?? rLenth) & 0x7FFFFFFF)); 

      stream.Write(value, rOffset, rCount); 
      done = true; 
     } 
     catch { done = false; } 
     return stream; 
    } 
}