問題があります:C#でテキストファイルから行を削除するにはどうすればよいですか?
ファイルを読み取り、メモリ内の行を削除し、内容をファイルに戻します(上書き)。ファイルが大きい場合は、行ごとに読み取って、一時ファイルを作成し、後で元のファイルを置き換えることができます。
very大きなファイルの場合、私はこのようなことをします
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");
Update私はもともと2009年にこれを書き直しましたが、アップデートで面白いかもしれないと思いました。今日、 LINQおよび遅延実行 を使用して上記を達成できました
var tempFile = Path.GetTempFileName();
var linesToKeep = File.ReadLines(fileName).Where(l => l != "removeme");
File.WriteAllLines(tempFile, linesToKeep);
File.Delete(fileName);
File.Move(tempFile, fileName);
上記のコードは、最初の例とほぼ同じで、1行ずつ読み取り、メモリに最小限のデータを保持しています。
ただし、免責事項が必要な場合があります。ここではテキストファイルについて説明しているので、ディスクを中間ストレージメディアとして使用する必要はほとんどありません。非常に大きなログファイルを処理していない場合は、代わりに内容をメモリに読み込むのに問題はなく、一時ファイルを処理する必要はありません。
File.WriteAllLines(fileName,
File.ReadLines(fileName).Where(l => l != "removeme").ToList());
.ToList
は、即時実行を強制するためにここで重要です。また、すべての例では、テキストファイルがUTF-8でエンコードされていることを前提としています。
私はジョン・サンダースに同意します、これは実際にはC#固有ではありません。ただし、質問に答えるには、基本的にファイルを書き換える必要があります。これを行うには2つの方法があります。
File.ReadAllLines
)List<string>
に変換してから行を削除するのがおそらく最も簡単です)File.WriteAllLines
)-ToArray
を使用して、潜在的にList<string>
を文字列配列に変換します。つまり、十分なメモリがあることを知る必要があります。別の方法:
TextReader
/TextWriter
として、例えばFile.OpenText
とFile.CreateText
で)TextReader.ReadLine
)-削除したくない場合は、出力ファイルに書き込む(TextWriter.WriteLine
)using
ステートメントを使用する場合、これは自動的に行われます)テキストファイルからアイテムを削除するには、まずすべてのテキストをリストに移動し、必要なアイテムを削除します。次に、リストに保存されているテキストをテキストファイルに書き込みます。
List<string> quotelist=File.ReadAllLines(filename).ToList();
string firstItem= quotelist[0];
quotelist.RemoveAt(0);
File.WriteAllLines(filename, quotelist.ToArray());
return firstItem;
Markus Olssonが提案したものを拡張し、複数の検索文字列といくつかのイベントを追加するこのクラスを思い付きました。
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; }
}
使用法:
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");
ファイルから行を削除するメソッドを書きました。
このプログラムはusing System.IO
を使用します。
私のコードを参照してください:
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());
}
}
私はとても単純に:
なぜこれを使用できないのですか?まず、配列を作成します。
string[] lines = File.ReadAllLines(openFileDialog1.FileName);
次に、削除する必要がある行を検索し、「」に置き換えます。
lines[x].Replace(lines[x], "");
できた!