J'ai un problème: comment puis-je supprimer une ligne d'un fichier texte en C #?
Lisez le fichier, supprimez la ligne en mémoire et replacez le contenu dans le fichier (écrasement). Si le fichier est volumineux, vous souhaiterez peut-être le lire ligne par ligne et créer un fichier temporaire, en remplaçant ultérieurement le fichier d'origine.
Pour les 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 J'ai écrit ceci à l'origine en 2009 et je pensais que cela pourrait être intéressant avec une mise à jour. Aujourd'hui, vous pouvez accomplir ce qui précède en utilisant LINQ et l'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 identique au premier exemple, lisant ligne par ligne et gardant une quantité minimale de données en mémoire.
Une clause de non-responsabilité pourrait toutefois être utile. Puisque nous parlons de fichiers texte ici, vous auriez très rarement à utiliser le disque comme support de stockage intermédiaire. Si vous ne traitez pas de fichiers journaux très volumineux, la lecture du contenu en mémoire ne devrait pas poser de problème et évitez de traiter le fichier temporaire.
File.WriteAllLines(fileName,
File.ReadLines(fileName).Where(l => l != "removeme").ToList());
Notez que le .ToList
est crucial ici pour forcer une exécution immédiate. Notez également que tous les exemples supposent que les fichiers texte sont codés en UTF-8.
Je suis d'accord avec John Saunders, ce n'est pas vraiment spécifique à C #. Cependant, pour répondre à votre question: vous devez fondamentalement réécrire le fichier. Vous pouvez le faire de deux manières.
File.ReadAllLines
)List<string>
puis de supprimer la ligne).File.WriteAllLines
) - convertissez éventuellement le List<string>
dans un tableau de chaînes à l'aide de ToArray
Cela signifie que vous devez savoir que vous avez assez de mémoire cependant. Une alternative:
TextReader
/TextWriter
, par exemple avec File.OpenText
et File.CreateText
)TextReader.ReadLine
) - si vous ne voulez pas la supprimer, écrivez-la dans le fichier de sortie (TextWriter.WriteLine
)using
pour les deux, cela se fera automatiquement)Pour supprimer un élément d'un fichier texte, déplacez d'abord tout le texte dans une liste et supprimez l'élément de votre choix. Ensuite, écrivez 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;
J'ai étendu ce que Markus Olsson avait suggéré et proposé 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; }
}
Usage:
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");
Je voudrais très simplement:
J'ai écrit une méthode pour supprimer des lignes 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());
}
}
Pourquoi ne pas utiliser ceci? D'abord, créez un tableau:
string[] lines = File.ReadAllLines(openFileDialog1.FileName);
Recherchez ensuite la ligne à supprimer et remplacez-la par "":
lines[x].Replace(lines[x], "");
Terminé!