Comprobación de C# para el lector binario final del archivo


Estaba buscando una manera de comprobar si he llegado al final de un archivo para mi lector binario y una sugerencia fue utilizar PeekChar como tal

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

Sin embargo, parece que me he encontrado con un problema

Unhandled Exception: System.ArgumentException: The output char buffer is too sma
ll to contain the decoded characters, encoding 'Unicode (UTF-8)' fallback 'Syste
m.Text.DecoderReplacementFallback'.
Parameter name: chars
   at System.Text.Encoding.ThrowCharsOverflow()
   at System.Text.Encoding.ThrowCharsOverflow(DecoderNLS decoder, Boolean nothin
gDecoded)
   at System.Text.UTF8Encoding.GetChars(Byte* bytes, Int32 byteCount, Char* char
s, Int32 charCount, DecoderNLS baseDecoder)
   at System.Text.DecoderNLS.GetChars(Byte* bytes, Int32 byteCount, Char* chars,
 Int32 charCount, Boolean flush)
   at System.Text.DecoderNLS.GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteC
ount, Char[] chars, Int32 charIndex, Boolean flush)
   at System.Text.DecoderNLS.GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteC
ount, Char[] chars, Int32 charIndex)
   at System.IO.BinaryReader.InternalReadOneChar()
   at System.IO.BinaryReader.PeekChar()

Así que tal vez PeekChar no es la mejor manera de hacerlo, y no creo que deba usarse de esa manera porque estoy revisando la posición actual de mi lector y no realmente lo que se supone que debe ser el siguiente personaje.

Author: That Umbrella Guy, 2012-06-08

4 answers

Hay una forma más precisa de comprobar si hay EOF cuando se trabaja con datos binarios. Evita todos los problemas de codificación que vienen con el enfoque PeekChar y hace exactamente lo que se necesita: verificar si la posición del lector está al final del archivo o no.

while (inFile.BaseStream.Position != inFile.BaseStream.Length)
{
   ...
}
 68
Author: That Umbrella Guy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-22 03:17:01

Envolviéndolo en un Método de extensión personalizado que extenderá la clase BinaryReader agregando el método EOF que falta.

public static class StreamEOF {

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

Así que ahora puedes escribir:

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

:) ... asumiendo que has creado infile en algún lugar como este:

var infile= new BinaryReader();

Nota: var es una escritura implícita. Feliz de encontrarlo - es otra pieza del rompecabezas para el código bien estilo en C#. : D

 3
Author: Un Peu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-19 04:16:34

Este trabajo para mí:

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
Author: user1803917,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-26 16:19:25

Añadiré mi sugerencia: si no necesita la parte de "codificación" del lector BinaryReader (por lo que no usa los varios ReadChar/ReadChars/ReadString), puede usar un codificador que nunca lanzará y que siempre es de un byte por char. Encoding.GetEncoding("iso-8859-1") es perfecto para esto. Se pasa como parámetro del constructor BinaryReader. La codificación iso-8859-1 es una codificación de un byte por carácter que mapea 1:1 todos los primeros 256 caracteres de Unicode (así que el byte 254 es el char 254 por ejemplo)

 0
Author: xanatos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-04 12:53:44