Lecture de fichiers texte, ligne par ligne, avec le décalage exact/déclaration de la position
Mon simple exigence: la Lecture d'un énorme (> un million) en ligne fichier de test (Pour cet exemple, supposons qu'elle est un CSV de quelques sortes), et en gardant une référence au début de la ligne, pour accélérer la recherche dans l'avenir (lire une ligne, en commençant par X).
J'ai essayé de la naïve et facile d'abord, à l'aide d'un StreamWriter
et accès à la sous-jacentes BaseStream.Position
. Malheureusement, cela ne fonctionne pas comme je l'ai prévu:
Donné un dossier contenant les éléments suivants
Foo
Bar
Baz
Bla
Fasel
et ce code très simple
using (var sr = new StreamReader(@"C:\Temp\LineTest.txt")) {
string line;
long pos = sr.BaseStream.Position;
while ((line = sr.ReadLine()) != null) {
Console.Write("{0:d3} ", pos);
Console.WriteLine(line);
pos = sr.BaseStream.Position;
}
}
la sortie est:
000 Foo
025 Bar
025 Baz
025 Bla
025 Fasel
Je peux imaginer que le flux est d'essayer d'être utile/efficace et peut-lit (gros) morceaux chaque fois que de nouvelles données sont nécessaires. Pour moi, c'est mauvais..
La question, enfin: une façon d'obtenir l' (byte, char) de décalage lors de la lecture d'un fichier ligne par ligne, sans l'aide d'une base de Flux et de jouer avec \r \n \r\n et de codage de la chaîne etc. manuellement? Pas une grosse affaire, vraiment, je n'aime pas à construire des choses qui existent peut-être déjà..
OriginalL'auteur Benjamin Podszun | 2010-04-07
Vous devez vous connecter pour publier un commentaire.
Vous pouvez créer un
TextReader
wrapper, qui permettrait de suivre la position actuelle dans la baseTextReader
:Vous pouvez ensuite l'utiliser comme suit :
Cette solution est très bien aussi longtemps que vous le souhaitez de la position de caractère, plutôt que la position en octets. Si le fichier sous-jacent a une Marque d'Ordre des Octets (BOM), il sera de compenser, ou s'il utilise des caractères multi-octets, la correspondance 1:1 entre les personnages et les octets ne tient plus.
D'accord, ne fonctionne que pour un seul octet de caractères codés en ASCII par exemple. Si, par exemple, votre fichier sous-jacent est en Unicode, chaque personnage aura 2 ou 4 octets codés. La mise en œuvre ci-dessus est de travailler sur un flux de caractères, pas un flux d'octets, de sorte que vous obtiendrez le caractère décalages qui ne sera pas de carte sur la réelle octet positions que chaque personnage peut être 2 ou 4 octets. Par exemple, la deuxième position de caractère sera signalé comme indice 1, mais la position en octets seront effectivement indice 2 ou 4. Si il y a un BOM (Byte Order Mark) ce sera encore ajouter des octets supplémentaires à la véritable sous-jacent position d'octet.
OriginalL'auteur Thomas Levesque
Après la recherche, de test et de faire quelque chose de fou, il y a mon code afin de le résoudre (je suis actuellement en utilisant ce code dans mon produit).
OriginalL'auteur Quynh Nguyen
Si Thomas Levesque de la solution fonctionne bien, voici la mienne. Il utilise la réflexion de sorte qu'il sera plus lent, mais c'est le codage indépendant. En Plus j'ai ajouté Chercher de l'extension.
OriginalL'auteur Sergey Alekseev
C'est vraiment difficile.
Après un très long et épuisant énumération des différentes solutions dans l'internet (y compris les solutions de ce fil, merci à vous!) J'ai dû créer mon propre vélo.
J'avais exigences suivantes:
Stable - octet d'erreur est immédiatement visible lors de l'utilisation. Malheureusement pour moi, plusieurs implémentations j'ai trouvé l'ont été avec des problèmes de stabilité
Pourriez-vous partager ce fichier en quelque sorte?
OriginalL'auteur Anton Purin
Serait-ce de travailler:
Darn - je viens de poster une réponse similaire explicitement invoqué un retour à la ligne cohérente séparateur...
Alors je pense que vous seriez mieux de le faire manuellement avec StreamReader.Read().
Hehe. Comme je l'ai dit: être la voie, au lieu d'utiliser un simple Flux - si ce sont les deux seules options que j'ai rouler un dé et vivre avec les conséquences: Soit la cohérence de séparateurs (mauvais pour les fichiers qui ont été traitées sur plus d'une plateforme, de copier/collé de mauvais éditeurs, etc) ou le Flux des trucs (ennuyeux faible niveau de la ligne d'analyse et de codage de la chaîne désordre, beaucoup de chaudière plaque de code pour un semblant de faible rendement)
Qui ne l'aide pas beaucoup. J'ai laisser tomber l'ensemble de la
StreamReader
. MêmeRead()
sur elle conduit à un bloc de lecture sur le flux sous-jacent et déplace leBaseStream.Position
à 25 pour mon exemple. Après char.OriginalL'auteur Sani Singh Huttunen