2017-04-26 1 views
0

Je veux un moyen plus rapide de filtrer tous les emails qui se terminent par un caractère spécial dans un gros fichier texte (plus de 200MB) en utilisant C#le moyen le plus rapide de filtrer tous les emails se termine par un caractère spécial dans un gros fichier texte en utilisant C#

var lines = File.ReadAllLines(file path); 

foreach(var line in lines) 
{ 
    if (line.EndsWith(myWord)) 
    { 
    outputEmails.Text += line + Environment.NewLine; 
    } 
} 

ce code est très lent pour atteindre mon objectif.

+0

lecteur de flux Utilisez au lieu de charger le fichier entier en mémoire –

Répondre

2

Utilisation File.ReadLines:

foreach (var line in File.ReadLines("file path")) 
{ 
    if (line.EndsWith(myWord)) 
    { 
     outputEmails.Text += line + Environment.NewLine; 
    } 
} 

En interne, il utilise StreamReader de sorte que vous ne chargez pas le fichier en mémoire avant de le lire.


Des performances encore meilleures peuvent être atteintes avec memory mapped files. Cela permet d'économiser des opérations de copie de mémoire supplémentaires lors de la lecture du contenu du fichier.

string line; 
var stringBuilder = new StringBuilder(); 
using (var memoryMappedFile = System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(@"D:\Temp\test.txt")) 
using (var viewStream = memoryMappedFile.CreateViewStream()) 
using (var streamReader = new StreamReader(viewStream)) 
{ 
    while ((line = streamReader.ReadLine()) != null) 
     if (line.EndsWith(myWord)) 
      stringBuilder.AppendLine(line); 
} 
outputEmails.Text = stringBuilder.ToString(); 

Et oui, comme les autres réponses disent, en utilisant StringBuilder au lieu de concaténation de chaîne brute sera également un code plus rapide, surtout lorsque plusieurs lignes correspondent à condition de filtre.

1

Si vous voulez optimiser quelque chose, vous devriez utiliser des tests de performance. Mais il faut travailler plus vite:

 string line; 
     var result = new StringBuilder(); 
     using (var reader = new StreamReader(fileName)) 
     { 
      while ((line = reader.ReadLine()) != null) 
      { 
       if (line.EndsWith(myWord)) 
        result.AppendLine(line); 
      } 
     } 
     outputEmails.Text = result.ToString(); 

Avantages ici:

1) Utilisez StreamReader pour lire par ligne de fichiers en ligne au lieu de tout en un temps. Dans ce cas, vous réduisez la consommation de mémoire. De plus, vous pouvez rendre votre code asynchrone en utilisant ReadLineAsync.

2) Avec StringBuilder, vous ne créez pas de nouvelles instances de chaîne dans chaque concaténation.

Espérons que cela aide.

1

manière la plus rapide et la plus optimisée est StreamReader avec StringBuilder

StringBuilder builder = new StringBuilder(); 
using (StreamReader reader = new StreamReader(@"c:\email.txt")) 
{ 
    while (!reader.EndOfStream) 
    { 
     var line = reader.ReadLine(); 
     if (line.EndsWith(myWord)) 
     { 
      builder.AppendLine(line); 
     } 
    } 
} 
outputEmails.Text = builder.ToString(); 
+0

@DmitryEgorov vous avez raison, merci pour aperçoive. Je vais éditer mon code. – Nino