Je veux lire un fichier texte ligne par ligne. Je voulais savoir si je le fais le plus efficacement possible dans le cadre des choses .NET C #.
Voici ce que j'essaie jusqu'à présent:
var filestream = new System.IO.FileStream(textFilePath,
System.IO.FileMode.Open,
System.IO.FileAccess.Read,
System.IO.FileShare.ReadWrite);
var file = new System.IO.StreamReader(filestream, System.Text.Encoding.UTF8, true, 128);
while ((lineOfText = file.ReadLine()) != null)
{
//Do something with the lineOfText
}
c#
.net
performance
file-io
text-files
Loren C Fortner
la source
la source
Fastest
vous dire des perspectives de performance ou de développement?filestream = new FileStream
dans uneusing()
déclaration pour éviter d'éventuels problèmes ennuyeux avec leRéponses:
Pour trouver le moyen le plus rapide de lire un fichier ligne par ligne, vous devrez effectuer une analyse comparative. J'ai fait quelques petits tests sur mon ordinateur mais vous ne pouvez pas vous attendre à ce que mes résultats s'appliquent à votre environnement.
Utilisation de StreamReader.ReadLine
C'est fondamentalement votre méthode. Pour une raison quelconque, vous définissez la taille du tampon sur la plus petite valeur possible (128). Augmenter cela augmentera généralement les performances. La taille par défaut est 1 024 et d'autres bons choix sont 512 (la taille du secteur dans Windows) ou 4 096 (la taille du cluster dans NTFS). Vous devrez exécuter un benchmark pour déterminer une taille de tampon optimale. Un tampon plus gros n'est - sinon plus rapide - du moins pas plus lent qu'un tampon plus petit.
Le
FileStream
constructeur vous permet de spécifier FileOptions . Par exemple, si vous lisez un gros fichier séquentiellement du début à la fin, vous pouvez en bénéficierFileOptions.SequentialScan
. Encore une fois, l'analyse comparative est la meilleure chose que vous puissiez faire.Utilisation de File.ReadLines
Cela ressemble beaucoup à votre propre solution, sauf qu'elle est implémentée à l'aide d'un
StreamReader
avec une taille de tampon fixe de 1 024. Sur mon ordinateur, cela entraîne des performances légèrement meilleures par rapport à votre code avec une taille de tampon de 128. Cependant, vous pouvez obtenir la même augmentation de performances en utilisant une taille de tampon plus grande. Cette méthode est implémentée à l'aide d'un bloc itérateur et ne consomme pas de mémoire pour toutes les lignes.Utilisation de File.ReadAllLines
Cela ressemble beaucoup à la méthode précédente, sauf que cette méthode développe une liste de chaînes utilisées pour créer le tableau de lignes renvoyé, de sorte que les besoins en mémoire sont plus élevés. Cependant, il revient
String[]
et neIEnumerable<String>
vous permet pas d'accéder au hasard aux lignes.Utilisation de String.Split
Cette méthode est considérablement plus lente, au moins sur les gros fichiers (testée sur un fichier de 511 Ko), probablement en raison de la façon dont elle
String.Split
est implémentée. Il alloue également un tableau pour toutes les lignes, augmentant la mémoire requise par rapport à votre solution.Ma suggestion est d'utiliser
File.ReadLines
car il est propre et efficace. Si vous avez besoin d'options de partage spéciales (par exemple que vous utilisezFileShare.ReadWrite
), vous pouvez utiliser votre propre code mais vous devez augmenter la taille du tampon.la source
Si vous utilisez .NET 4, utilisez simplement
File.ReadLines
qui fait tout pour vous. Je soupçonne qu'il est à peu près le même que le vôtre, sauf qu'il peut également utiliserFileOptions.SequentialScan
et un tampon plus grand (128 semble très petit).la source
ReadLines()
est qu'il est paresseux et fonctionne donc bien avec LINQ.Bien que ce
File.ReadAllLines()
soit l'un des moyens les plus simples de lire un fichier, c'est aussi l'un des plus lents.Si vous souhaitez simplement lire des lignes dans un fichier sans faire grand-chose, selon ces repères , le moyen le plus rapide de lire un fichier est la méthode séculaire de:
Cependant, si vous devez faire beaucoup avec chaque ligne, cet article conclut que la meilleure façon est la suivante (et il est plus rapide de pré-allouer une chaîne [] si vous savez combien de lignes vous allez lire):
la source
Utilisez le code suivant:
C'était une énorme différence dans les performances de lecture.
Cela se fait au détriment de la consommation de mémoire, mais ça vaut vraiment le coup!
la source
File.ReadAllLines
Il y a un bon sujet à ce sujet dans la question de débordement de pile . .
Ça dit:
la source
Si la taille du fichier n'est pas grande, il est plus rapide de lire le fichier entier et de le diviser ensuite
la source
File.ReadAllLines()
File.ReadAllLines
taille du tampon soit fixe, car la taille du fichier est connue.File.ReadAllLines
crée une liste et ajoute à cette liste dans une boucle en utilisantStreamReader.ReadLine
(avec une réallocation potentielle du tableau sous-jacent). Cette méthode utilise une taille de tampon par défaut de 1024. CelaStreamReader.ReadToEnd
évite la partie d'analyse de ligne et la taille du tampon peut être définie dans le constructeur si vous le souhaitez.Si vous avez suffisamment de mémoire, j'ai trouvé des gains de performances en lisant le fichier entier dans un flux de mémoire , puis en ouvrant un lecteur de flux sur celui-ci pour lire les lignes. Tant que vous prévoyez de lire le fichier dans son intégralité, cela peut apporter quelques améliorations.
la source
File.ReadAllLines
semble être un meilleur choix alors.Vous ne pouvez pas aller plus vite si vous souhaitez utiliser une API existante pour lire les lignes. Mais lire des morceaux plus gros et trouver manuellement chaque nouvelle ligne dans le tampon de lecture serait probablement plus rapide.
la source