2010-06-03 11 views
3

Je suis en train d'analyser un très grand fichier d'enregistrements (un par ligne, chacun de longueur variable), et je voudrais garder une trace du nombre d'octets que j'ai lus dans le fichier afin que je puisse récupérer dans l'événement d'un échec.Comment compter le nombre d'octets lus par TextReader.ReadLine()?

j'écrit ce qui suit:

using (TextReader myTextReader = CreateTextReader()) 
{ 
    string record = myTextReader.ReadLine(); 
    bytesRead += record.Length; 
    ParseRecord(record); 
} 

Toutefois, cela ne fonctionne pas depuis ReadLine() bandes des caractères CR/LF dans la ligne. En outre, une ligne peut être terminée par des caractères CR, LF ou CRLF, ce qui signifie que je ne peux pas ajouter 1 à bytesRead.

Existe-t-il un moyen facile d'obtenir la longueur de ligne réelle, ou est-ce que j'écris ma propre méthode ReadLine() en termes d'opérations granulaires Read()?

Répondre

2

Obtenir la position actuelle du flux sous-jacent ne sera pas utile, puisque le StreamReader en mémoire tampon des données lues à partir du flux.

Essentiellement, vous ne pouvez pas faire cela sans écrire votre propre StreamReader. Mais en as-tu vraiment besoin?

Je comptais simplement le nombre de lignes lues.

Bien sûr, cela signifie que la position à une ligne spécifique, vous aurez besoin de lire les lignes N plutôt que de chercher simplement à un décalage, mais ce qui est mal à cela? Avez-vous déterminé que la performance sera inacceptable?

0

Venez y penser, je peux utiliser un StreamReader et obtenir la position actuelle du flux sous-jacent comme suit.

using (StreamReader myTextReader = CreateStreamReader()) 
{ 
    stringRecord = myTextReader.ReadLine(); 
    bytesRead += myTextReader.BaseStream.Position; 
    ParseRecord(record); 
    // ... 
} 
+2

Cela ne fonctionne que si le flux sous-jacent soutient la recherche, qui travaille probablement dans votre cas, mais je tiens à souligner que cette méthode ne fonctionnera pas pour tous les cas. –

+2

Il peut également y avoir un problème si le StreamReader est mis en mémoire tampon où le BaseStream avance en segments. – sisve

+0

Cela ne fonctionne définitivement pas car pour des raisons de performances, TextReader lit les flux de base en blocs de 4096 octets au lieu de byte by byte. C'est en fait la même chose que ce que Simon a dit. –

1

Un TextReader lit des chaînes, qui sont des caractères qui [selon l'encodage] n'est pas égal à octets.

Que diriez-vous simplement stocker nombre de lignes lues, et sauter juste que beaucoup de lignes lors de la récupération? Je suppose qu'il s'agit de ne pas traiter ces lignes, sans nécessairement éviter de les lire dans le flux.

+0

Dans mon cas, je peux supposer que le fichier que je suis en train de lire contient des caractères ASCII à un octet. Aussi, bien que je puisse stocker le numéro de ligne, j'espérais chercher dans le flux, en évitant d'avoir à lire chaque ligne que j'ai déjà analysée (les lignes ne sont pas de longueur fixe). –