web-dev-qa-db-fra.com

Vérification de C # pour la fin du fichier du lecteur binaire

Je cherchais un moyen de vérifier si mon lecteur binaire était arrivé à la fin d'un fichier et j'ai suggéré d'utiliser PeekChar en tant que tel.

while (inFile.PeekChar() > 0)
{
    ...
}

Cependant, il semble que j'ai rencontré un problème

 Exception non gérée: System.ArgumentException: le tampon de caractères de sortie est trop petit pour contenir les caractères décodés, codant le 'système de repli' Unicode (UTF-8) '
 M
 Nom du paramètre: chars 
 à System.Text.Encoding.ThrowCharsOverflow () 
 à System.Text.Encoding.ThrowCharsOverflow (décodeur DecoderNLS, Boolean rien.... gDécodé) 
 à System.Text.UTF8Encoding.GetChars (octet * octets, Int32 octetCompte, Char * caractère 
 s, Int32 caractèreCompte, DecoderNLS baseDecoder) 
 sur System.Text.DecoderNLS.GetChars (Byte * octets, Int32 byteCount, Char * caractères, 
 Int32 charCount, Valeur booléenne) 
 at System.Text.DecoderNLS.GetChars (Byte [] octets, Int32 byteIndex, Int32 byteC 
 ount, Char [] caractères, Int32 charIndex, Boolean flush) 
 at System.Text.DecoderNLS.GetChars (Byte [] octets, Int32 byteIndex, Int32 byteC 
 ount, Char [] caractères, Int32 charIndex) 
 à l'adresse System.IO.BinaryReader.InternalReadOneChar () 
 à l'adresse System.IO.BinaryReader.PeekChar () 

Alors peut-être que PeekChar n'est pas la meilleure façon de le faire, et je ne pense pas que cela devrait même être utilisé de cette façon, car je vérifie la position actuelle de mon lecteur et pas vraiment ce que le prochain caractère est supposé être.

36

Il existe un moyen plus précis de vérifier EOF lorsque vous travaillez avec des données binaires. Il évite tous les problèmes d'encodage inhérents à l'approche PeekChar et fait exactement ce qu'il faut: vérifier si la position du lecteur est à la fin du fichier ou non.

while (inFile.BaseStream.Position != inFile.BaseStream.Length)
{
   ...
}
74
That Umbrella Guy

Envelopper dans une Méthode d'extension personnalisée qui étendra la classe BinaryReader en ajoutant la méthode manquante EOF.

public static class StreamEOF {

    public static bool EOF( this BinaryReader binaryReader ) {
        var bs = binaryReader.BaseStream;
        return ( bs.Position == bs.Length);
    }
}

Alors maintenant, vous pouvez simplement écrire:

while (!infile.EOF()) {
   // Read....
}

:) ... en supposant que vous ayez créé infile quelque part comme ceci:

var infile= new BinaryReader();

Remarque: var est un typage implicite. Heureux de le trouver - c'est une autre pièce de puzzle pour un code bien stylé en C #. :RÉ

3
Un Peu

Ce travail pour moi:

using (BinaryReader br = new BinaryReader(File.Open(fileName,   
FileMode.Open))) {
            //int pos = 0;
            //int length = (int)br.BaseStream.Length;
            while (br.BaseStream.Position != br.BaseStream.Length) {
                string nume = br.ReadString ();
                string prenume = br.ReadString ();
                Persoana p = new Persoana (nume, prenume);
                myArrayList.Add (p);
                Console.WriteLine ("ADAUGAT XXX: "+ p.ToString());
                //pos++;
            }
        }
1
user1803917

J'ajouterai ma suggestion: si vous n'avez pas besoin de la partie "encoding" de BinaryReader (pour ne pas utiliser les différents ReadChar/ReadChars/ReadString), vous pouvez utiliser un encodeur qui ne jettera jamais et qui est toujours un octet par caractère. Encoding.GetEncoding("iso-8859-1") est parfait pour cela. Vous le transmettez en tant que paramètre du constructeur BinaryReader. Le codage iso-8859-1 est un codage d'un octet par caractère qui mappe 1: 1 les 256 premiers caractères d'Unicode (donc, la byte 254 est la char 254 par exemple).

0
xanatos