Mes exigences simples: lire un énorme fichier de test de ligne (>> un million) (pour cet exemple suppose qu'il s'agit d'une CSV de certaines sortes) et de tenir une référence au début de cette ligne pour une recherche plus rapide à l'avenir (lire une ligne , à partir de x).
J'ai essayé le moyen naïf et facile d'abord, en utilisant un donné un fichier contenant le fichier suivant p> et ce code très simple p> StreamWriter Code> et accédant à la
astresseam.position code>. Malheureusement, cela ne fonctionne pas comme je l'ai dit: p>
000 Foo
025 Bar
025 Baz
025 Bla
025 Fasel
5 Réponses :
Cela fonctionnerait-il:
using (var sr = new StreamReader(@"C:\Temp\LineTest.txt")) { string line; long pos = 0; while ((line = sr.ReadLine()) != null) { Console.Write("{0:d3} ", pos); Console.WriteLine(line); pos += line.Length; } }
Malheureusement non, parce que je dois accepter différents types de nouvelles lignes (pensez que ceci \ n, \ r \ n, \ r) et que le nombre serait asymétrique. Cela pourrait fonctionner si j'insiste pour avoir un séparateur cohérent i> Newline (il pourrait très bien être mélangé dans la pratique) et si je le sondis d'abord, de connaître le décalage réel. Donc - j'essaie d'éviter de descendre cette route.
@Benjamin: Darn - Je viens de poster une réponse similaire qui s'appuie explicitement sur un séparateur de nouvelle ligne cohérent ...
Ensuite, je pense que vous feriez mieux de le faire manuellement avec StreamReader.Lead ().
@Jon: hehe. Comme je l'ai dit: que pourrait i> être le chemin, au lieu d'utiliser un flux simple - si ce sont les deux seules options que je dois rouler un dés et vivre avec les conséquences: soit les séparateurs cohérents (mauvais Pour les fichiers qui ont été traités sur plusieurs plate-forme, copiez / collé dans des éditeurs incorrects, etc.), etc.) ou sur les trucs de flux (analyse de la ligne de niveau de niveau basse et en chaîne, encodent beaucoup de code de plaque de chaudière pour un rendement apparemment bas)
Cela n'en aiderait pas beaucoup. Je dois abandonner tout le streamreader code>. Même
Lire () Code> On dirige un bloc sur le flux sous-jacent et déplace le
astream.position code> à 25 pour mon échantillon. Après un caractère i>.
Vous pouvez créer un wrapper vous pouvez alors utiliser comme suit: p> textreader code>, qui suivrait la position actuelle dans la base
textreader code>:
Semble fonctionner. Cela semble si évident maintenant .. Merci beaucoup.
Cette solution convient aussi longtemps que vous voulez la position de caractère, plutôt que la position d'octet. Si le fichier sous-jacent a une barre d'ordre d'octets (BOM), il compensera, ou s'il utilise des caractères multi-octets, la correspondance 1: 1 entre les caractères et les octets ne contiennent plus.
D'accord, fonctionne uniquement pour les caractères codés par octet unique. Ascii. Si, par exemple, votre fichier sous-jacent est Unicode, chaque caractère sera codé de 2 ou 4 octets. La mise en œuvre ci-dessus fonctionne sur un flux de caractères, pas un flux d'octets, vous obtiendrez donc des décalages de caractères qui ne feront pas la mapper sur les positions d'octets réels, chaque caractère peut être de 2 ou 4 octets. Par exemple, la deuxième position de caractère sera signalée en tant qu'index 1, mais la position des octets sera effectivement index 2 ou 4. S'il y a une bombe (marque d'ordre d'octets), cela ajoutera à nouveau des octets supplémentaires à la véritable position d'octet sous-jacente.
Bien que la solution de Thomas Levesque fonctionne bien, voici la mienne. Il utilise la réflexion de sorte qu'il sera plus lent, mais il est indépendant de l'encodage. De plus, j'ai également ajouté la recherche d'extension.
Après avoir cherché, tester et faire quelque chose de fou, mon code résoudra (je suis actuellement en train d'utiliser ce code dans mon produit).
C'est un problème vraiment difficile. Après une énumération très longue et épuisante de différentes solutions sur Internet (y compris des solutions de ce fil, merci!) Je devais créer mon propre vélo.
J'avais suivi les exigences: p>
Stable fort> - une erreur d'octet unique était immédiatement visible pendant l'utilisation. Malheureusement pour moi, plusieurs implémentations que j'ai trouvées étaient avec des problèmes de stabilité p>
J'ai un fichier journal, qui, lorsque vous avez lu avec OffseReader, le fait entrer dans une boucle infinie ...
Pourriez-vous partager ce fichier en quelque sorte?
Si vous réfléchissez à la classe System.IO.Stream, le tampon minimum autorisé est de 128 octets ... Je ne sais pas si cela vous aidera, mais sur un fichier plus long lorsque j'ai essayé cela, c'était la position la plus courte que je pouvais obtenir.