Comment supprimer une ligne d'un fichier texte en C#?

j'ai un problème: comment puis-je supprimer une ligne d'un fichier texte en C#?

36
demandé sur splattne 2009-03-21 10:19:30

8 réponses

Lire le fichier, supprimer la ligne dans la mémoire et placer le contenu dans le fichier (par écrasement). Si le fichier est grand, vous pourriez vouloir le lire ligne par ligne, et créer un fichier temp, remplaçant plus tard l'original.

24
répondu Sascha 2009-03-21 07:24:12

très gros fichiers je ferais quelque chose comme ça

string tempFile = Path.GetTempFileName();

using(var sr = new StreamReader("file.txt"))
using(var sw = new StreamWriter(tempFile))
{
    string line;

    while((line = sr.ReadLine()) != null)
    {
         if(line != "removeme")
             sw.WriteLine(line);
    }
}

File.Delete("file.txt");
File.Move(tempFile, "file.txt");

mise à Jour Je l'ai écrit à l'origine en 2009 et j'ai pensé qu'il pourrait être intéressant avec une mise à jour. Aujourd'hui, vous pouvez accomplir ce qui précède en utilisant LINQ et exécution différée

var tempFile = Path.GetTempFileName();
var linesToKeep = File.ReadLines(fileName).Where(l => l != "removeme");

File.WriteAllLines(tempFile, linesToKeep);

File.Delete(fileName);
File.Move(tempFile, fileName);

le code ci-dessus est presque exactement le même que le premier exemple, en lisant ligne par ligne et en gardant une quantité minimale de données en mémoire.

Un avertissement pourrait être dans l'ordre. Puisque nous parlons ici de fichiers texte, vous aurez très rarement à utiliser le disque comme un support de stockage intermédiaire. Si vous n'avez pas affaire à de très gros fichiers journaux, il ne devrait pas y avoir de problème à lire le contenu dans la mémoire à la place et éviter d'avoir à traiter le fichier temporaire.

File.WriteAllLines(fileName, 
    File.ReadLines(fileName).Where(l => l != "removeme").ToList());

notez que le .ToList est ici crucial pour forcer l'exécution immédiate. Notez également que tous les exemples supposent que les fichiers texte sont encodés UTF-8.

66
répondu Markus Olsson 2013-05-28 11:44:39

je suis d'accord avec John Saunders, ce n'est pas vraiment C# spécifiques. Cependant, pour répondre à votre question: vous avez besoin de réécrire le fichier. Il y a deux façons dont vous pouvez faire cette.

  • lire tout le fichier en mémoire (par exemple avec File.ReadAllLines)
  • supprimer la ligne offensante (dans ce cas, il est probablement plus facile de convertir le tableau string en un List<string> puis supprimer la ligne)
  • Écrire toutes les autres lignes (ex:File.WriteAllLines) - potentiellement convertir le List<string> dans un tableau de chaînes de nouveau à l'aide de ToArray

cela signifie Que vous devez savoir que vous avez suffisamment de mémoire. Une alternative:

  • Ouvrir le fichier d'entrée, et un nouveau fichier de sortie (comme un TextReader/TextWriter, p.ex. avec File.OpenText et File.CreateText)
  • Lire une ligne (TextReader.ReadLine) - si vous ne voulez pas le supprimer, écrivez-le dans le fichier de sortie (TextWriter.WriteLine)
  • lorsque vous avez lu toutes les lignes, fermez à la fois le lecteur et le auteur (si vous utilisez using consolidés pour les deux, cela va se faire automatiquement)
  • Si vous souhaitez remplacer l'entrée à la sortie, supprimez le fichier d'entrée, puis déplacez le fichier de sortie en place.
18
répondu Jon Skeet 2013-04-04 06:11:37

J'ai étendu ce que Markus Olsson a suggéré, et j'ai trouvé cette classe qui ajoute plusieurs chaînes de recherche et quelques événements:

public static class TextLineRemover
{
    public static void RemoveTextLines(IList<string> linesToRemove, string filename, string tempFilename)
    {
        // Initial values
        int lineNumber = 0;
        int linesRemoved = 0;
        DateTime startTime = DateTime.Now;

        // Read file
        using (var sr = new StreamReader(filename))
        {
            // Write new file
            using (var sw = new StreamWriter(tempFilename))
            {
                // Read lines
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    lineNumber++;
                    // Look for text to remove
                    if (!ContainsString(line, linesToRemove))
                    {
                        // Keep lines that does not match
                        sw.WriteLine(line);
                    }
                    else
                    {
                        // Ignore lines that DO match
                        linesRemoved++;
                        InvokeOnRemovedLine(new RemovedLineArgs { RemovedLine = line, RemovedLineNumber = lineNumber});
                    }
                }
            }
        }
        // Delete original file
        File.Delete(filename);

        // ... and put the temp file in its place.
        File.Move(tempFilename, filename);

        // Final calculations
        DateTime endTime = DateTime.Now;
        InvokeOnFinished(new FinishedArgs {LinesRemoved = linesRemoved, TotalLines = lineNumber, TotalTime = endTime.Subtract(startTime)});
    }

    private static bool ContainsString(string line, IEnumerable<string> linesToRemove)
    {
        foreach (var lineToRemove in linesToRemove)
        {
            if(line.Contains(lineToRemove))
                return true;
        }
        return false;
    }

    public static event RemovedLine OnRemovedLine;
    public static event Finished OnFinished;

    public static void InvokeOnFinished(FinishedArgs args)
    {
        Finished handler = OnFinished;
        if (handler != null) handler(null, args);
    }

    public static void InvokeOnRemovedLine(RemovedLineArgs args)
    {
        RemovedLine handler = OnRemovedLine;
        if (handler != null) handler(null, args);
    }
}

public delegate void Finished(object sender, FinishedArgs args);

public class FinishedArgs
{
    public int TotalLines { get; set; }
    public int LinesRemoved { get; set; }
    public TimeSpan TotalTime { get; set; }
}

public delegate void RemovedLine(object sender, RemovedLineArgs args);

public class RemovedLineArgs
{
    public string RemovedLine { get; set; }
    public int RemovedLineNumber { get; set; }
}

Utilisation:

        TextLineRemover.OnRemovedLine += (o, removedLineArgs) => Console.WriteLine(string.Format("Removed \"{0}\" at line {1}", removedLineArgs.RemovedLine, removedLineArgs.RemovedLineNumber));
        TextLineRemover.OnFinished += (o, finishedArgs) => Console.WriteLine(string.Format("{0} of {1} lines removed. Time used: {2}", finishedArgs.LinesRemoved, finishedArgs.TotalLines, finishedArgs.TotalTime.ToString()));
        TextLineRemover.RemoveTextLines(new List<string> { "aaa", "bbb" }, fileName, fileName + ".tmp");
6
répondu Håvard Fjær 2011-04-14 15:06:22

pour supprimer un élément du fichier texte, déplacez d'abord tout le texte dans une liste et supprimez l'élément que vous voulez. Puis écrire le texte stocké dans la liste dans un fichier texte

   List<string> quotelist=File.ReadAllLines(filename).ToList();
            string firstItem= quotelist[0];
            quotelist.RemoveAt(0);
            File.WriteAllLines(filename, quotelist.ToArray());
            return firstItem;
6
répondu Prakash Rajendran 2012-05-29 13:00:48

je serais très simplement:

  • ouvrir le fichier pour lire/écrire
  • Lecture/recherche à travers elle jusqu'à ce que le début de la ligne que vous voulez supprimer
  • définissez le pointeur d'écriture sur le pointeur de lecture courant
  • Lire jusqu'à la fin de la ligne, nous sommes de supprimer et de sauter le saut de ligne délimiteurs (en comptant le nombre de caractères que nous allons, nous allons l'appeler nline)
  • Lire octet par octet, et d'écrire chaque octet dans le fichier
  • une fois terminé tronquez le fichier vers (orig_length-nline).
3
répondu Adam Hawes 2009-03-21 08:17:09

Bonjour les gars, j'ai écrit une méthode pour supprimer des lignes à partir de fichiers. Ce programme utilise using System.IO

Voir mon code:

    void File_DeleteLine(int Line, string Path)
    {
        StringBuilder sb = new StringBuilder();
        using (StreamReader sr = new StreamReader(Path))
        {
            int Countup = 0;
            while (!sr.EndOfStream)
            {
                Countup++;
                if (Countup != Line)
                {
                    using (StringWriter sw = new StringWriter(sb))
                    {
                        sw.WriteLine(sr.ReadLine());
                    }
                }
                else
                {
                    sr.ReadLine();
                }
            }
        }
        using (StreamWriter sw = new StreamWriter(Path))
        {
            sw.Write(sb.ToString());
        }
    }
2
répondu Leonhard P. 2015-09-01 22:33:30

pourquoi ne peut pas utiliser cela? Tout d'abord, créez un tableau:

string[] lines = File.ReadAllLines(openFileDialog1.FileName);

ensuite, cherchez la ligne que vous devez supprimer et remplacez-la par "" :

lines[x].Replace(lines[x], "");

Fait!

1
répondu Marty Brant 2015-05-31 21:09:04