Différence entre la chaîne d'écriture et le tableau de caractères avec System.IO.BinaryWriter

StackOverflow https://stackoverflow.com/questions/1014727

Question

J'écris du texte dans un fichier binaire en C # et constate une différence de quantité écrite entre l'écriture d'une chaîne de caractères et celle d'un tableau de caractères. J'utilise System.IO.BinaryWriter et regarde BinaryWriter.BaseStream.Length au moment où les écritures se produisent. Voici mes résultats:

using(BinaryWriter bw = new BinaryWriter(File.Open(“data.dat”), Encoding.ASCII))
{
  string value = “Foo”;

  // Writes 4 bytes
  bw.Write(value);

  // Writes 3 bytes 
  bw.Write(value.ToCharArray());
}

Je ne comprends pas pourquoi la surcharge de chaîne écrit 4 octets alors que je n’écris que 3 caractères ASCII. Quelqu'un peut-il expliquer cela?

Était-ce utile?

La solution

La documentation de BinaryWriter.Write (string) indique qu'il écrit une chaîne avec un préfixe de longueur dans ce flux. Surcharge pour Écrire (char []) n'a pas de préfixe de ce type.

Il me semble que les données supplémentaires sont la longueur.

EDIT:

Juste pour être un peu plus explicite, utilisez Reflector. Vous verrez qu'il contient ce morceau de code dans la méthode Write (string) :

this.Write7BitEncodedInt(byteCount);

C’est un moyen de coder un entier en utilisant le moins d’octets possible. Pour les chaînes courtes (que nous utiliserions au jour le jour avec moins de 128 caractères), il peut être représenté en utilisant un octet. Pour les chaînes plus longues, il commence à utiliser plus d'octets.

Voici le code de cette fonction au cas où cela vous intéresserait:

protected void Write7BitEncodedInt(int value)
{
    uint num = (uint) value;
    while (num >= 0x80)
    {
        this.Write((byte) (num | 0x80));
        num = num >> 7;
    }
    this.Write((byte) num);
}

Après avoir préfixé la longueur à l'aide de ce codage, les octets des caractères du codage souhaité sont écrits.

Autres conseils

À partir de BinaryWriter.Write (chaîne) docs :

Écrit une chaîne avec le préfixe de longueur dans ce flux dans le codage actuel de BinaryWriter et avance la position actuelle du flux en fonction du codage utilisé et des caractères spécifiques en cours d'écriture dans le flux. .

Ce comportement est probablement tel que lors de la lecture du fichier en utilisant un BinaryReader , la chaîne peut être identifiée. (Par exemple, 3Foo3Bar6Foobar peut être analysé dans la chaîne "Foo", "Bar" et "Foobar" mais FooBarFoobar ne peut pas être.) En fait, BinaryReader.ReadString utilise exactement ces informations pour lire une chaîne à partir d'un fichier binaire.

À partir de BinaryWriter.Write (char []) docs :

Écrit un tableau de caractères dans le flux actuel et avance la position actuelle du flux en fonction du codage utilisé et des caractères spécifiques en cours d'écriture dans le flux.

Il est difficile d'exagérer à quel point les documents sur MSDN sont complets et utiles. Toujours les vérifier d'abord.

Comme déjà indiqué, BinaryWriter.Write (String) écrit la longueur de la chaîne dans le flux, avant d'écrire la chaîne elle-même.

Ceci permet à BinaryReader.ReadString () de savoir combien de temps la chaîne est longue.

using (BinaryReader br = new BinaryReader(File.OpenRead("data.dat")))
{
    string foo1 = br.ReadString();
    char[] foo2 = br.ReadChars(3);
}

Avez-vous regardé ce qui était écrit? Je devinerais un terminateur nul.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top