2009-10-03 12 views
4

Pour un projet que je fais, l'une des choses que je dois faire est de supprimer les premières lignes X d'un fichier texte. Je dis X parce que j'aurai besoin de faire cette routine plusieurs fois et chaque fois, les lignes à supprimer seront différentes, mais ils commenceront toujours depuis le début, supprimer le X d'abord et ensuite sortir les résultats à le même fichier.Comment supprimer les premières lignes "X" d'un fichier texte?

Je pense à faire quelque chose comme ça, que je Rassemblé d'autres tutoriels et des exemples que je lis:

String line = null; 

String tempFile = Path.GetTempFileName(); 
String filePath = openFileDialog.FileName; 

int line_number = 0; 
int lines_to_delete = 25; 

using (StreamReader reader = new StreamReader(originalFile)) { 
    using (StreamWriter writer = new StreamWriter(tempFile)) { 
     while ((line = reader.ReadLine()) != null) { 
      line_number++; 

      if (line_number <= lines_to_delete) 
       continue; 

      writer.WriteLine(line); 
     } 
    } 
} 

if (File.Exists(tempFile)) { 
    File.Delete(originalFile); 
    File.Move(tempFile, originalFile); 
} 

Mais je ne sais pas si cela fonctionnerait à cause de petites choses comme les numéros de ligne à partir de la ligne 0 ou autre ... aussi, je ne sais pas si c'est un bon code en termes d'efficacité et de forme.

Merci beaucoup.

Répondre

6

C'est OK, et ne semble pas qu'il aurait les problèmes off-by-one que vous craignez. Cependant, une approche plus légère serait offerte par deux boucles séparées - une pour simplement compter les X premières lignes du fichier d'entrée (et ne rien faire d'autre), une autre pour simplement copier les autres lignes d'entrée en sortie. À savoir, au lieu de votre seule boucle while, ont ...:

while ((line = reader.ReadLine()) != null) { 
     line_number++; 

     if (line_number > lines_to_delete) 
      break; 
    } 

    while ((line = reader.ReadLine()) != null) { 
     writer.WriteLine(line); 
    } 
+0

Cela fonctionne parce que quand je fais reader.ReadLine() à nouveau, il reprend la lecture là où il avait laissé, non? Si je voulais faire un autre lecteur appelé "lecteur" (comme ce serait dans une plus grande boucle qui répéterait ce processus plusieurs fois) je voudrais juste fermer "lecteur" et puis quand j'en ai fait un autre, il commencerait retour du début du fichier, correct? – ankushg

+0

@Unk, oui, aux deux questions dans ce commentaire. –

+0

Merci beaucoup! – ankushg

0

Vous pouvez lire le fichier dans un tableau de lignes, ignorez les premiers éléments, et d'écrire le dossier. L'inconvénient de cette approche est qu'elle va consommer la taille du fichier en mémoire. Votre approche (bien que très illisible, pas d'infraction) n'a pas ce problème de mémoire. Bien que les fichiers ne soient pas trop volumineux, il ne devrait pas y avoir de raison de s'inquiéter de l'utilisation de la mémoire.

Exemple:

string[] lines = System.IO.File.ReadAllLines("YourFile.txt").Skip(10).ToArray(); 
System.IO.File.WriteAllLines("OutFile.txt", lines); 
+0

Ouais, le problème principal est que le fichier est extrêmement grand et l'ordinateur sur lequel le programme serait exécuté n'est pas exactement top. J'utilise déjà un tas de tableaux pour les choses, c'est pourquoi je suis allé avec mon approche pour le faire; le lire et l'écrire sur place. Merci pour votre aide, de toute façon. – ankushg

+0

Oops, mon mauvais, oubliez le ToArray() –

8

Je l'aime court ...

File.WriteAllLines(
    fileName, 
    File.ReadAllLines(fileName).Skip(numberLinesToSkip).ToArray()); 
+0

Belle solution propre. Cela causera des problèmes si le fichier source est trop grand car il lit le fichier entier en mémoire. – LukeH

+0

Oui, c'est vraiment propre, mais comme je l'ai mentionné dans le post de Charlie, le fichier est extrêmement volumineux et cette application ne sera pas exécutée sur une machine puissante ... Merci bien; Je ne connaissais pas toutes ces méthodes que vous avez utilisées et j'ai appris de nouvelles choses! – ankushg

2

J'aime votre approche, je ne vois rien de mal à cela. Si vous savez avec certitude qu'il s'agit de petits fichiers, alors les autres suggestions peuvent être un peu moins de code si cela vous intéresse.

Une version un peu moins bavard de ce que vous avez déjà:

using (StreamReader reader = new StreamReader(originalFile)) 
using (StreamWriter writer = new StreamWriter(tempFile)) 
{ 
    while(lines_to_delete-- > 0) 
     reader.ReadLine(); 
    while ((line = reader.ReadLine()) != null) 
     writer.WriteLine(line); 
} 
+0

Merci pour votre contribution! – ankushg

Questions connexes