Как удалить строку из текстового файла в C #? - PullRequest
40 голосов
/ 21 марта 2009

У меня проблема: как удалить строку из текстового файла в C #?

Ответы [ 8 ]

72 голосов
/ 21 марта 2009

Для очень больших файлов я бы сделал что-то вроде этого

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");

Обновление Первоначально я написал это еще в 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);

Приведенный выше код почти такой же, как и в первом примере, чтение строки за строкой и сохранение минимального объема данных в памяти.

Отказ от ответственности может быть в порядке, хотя. Поскольку здесь речь идет о текстовых файлах, вам очень редко придется использовать диск в качестве промежуточного носителя. Если вы не имеете дело с очень большими файлами журналов, не должно возникнуть проблем с чтением содержимого в память, и вам не придется иметь дело с временным файлом.

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

Обратите внимание, что .ToList имеет решающее значение для немедленного выполнения. Также обратите внимание, что во всех примерах предполагается, что текстовые файлы имеют кодировку UTF-8.

26 голосов
/ 21 марта 2009

Считайте файл, удалите строку из памяти и поместите содержимое обратно в файл (перезапись). Если файл большой, вы можете прочитать его строка за строкой и создать временный файл, а затем заменить его оригиналом.

19 голосов
/ 21 марта 2009

Я согласен с Джоном Сондерсом, это не совсем C #. Однако, чтобы ответить на ваш вопрос: вам в основном нужно переписать файл. Есть два способа сделать это.

  • Считать весь файл в память (например, с помощью File.ReadAllLines)
  • Удалить ошибочную строку (в этом случае, вероятно, проще всего преобразовать строковый массив в List<string>, а затем удалить строку)
  • Записать все остальные строки обратно (например, с File.WriteAllLines) - потенциально преобразовать List<string> в строковый массив снова, используя ToArray

Это значит, что вы должны знать, что у вас достаточно памяти. Альтернатива:

  • Открыть как входной файл, так и новый выходной файл (как TextReader / TextWriter, например, с File.OpenText и File.CreateText)
  • Читать строку (TextReader.ReadLine) - если вы не хотите ее удалять, запишите ее в выходной файл (TextWriter.WriteLine)
  • Когда вы прочитаете все строки, закройте и читателя, и писателя (если вы используете using операторов для обоих, это произойдет автоматически)
  • Если вы хотите заменить входные данные выходными, удалите входной файл, а затем переместите выходной файл на место.
7 голосов
/ 29 мая 2012

Чтобы удалить элемент из текстового файла, сначала переместите весь текст в список и удалите любой элемент, который вы хотите. Затем запишите текст, сохраненный в списке, в текстовый файл:

List<string> quotelist=File.ReadAllLines(filename).ToList();
string firstItem= quotelist[0];
quotelist.RemoveAt(0);
File.WriteAllLines(filename, quotelist.ToArray());
return firstItem;
6 голосов
/ 14 апреля 2011

Я расширил то, что предложил Маркус Олссон, и предложил этот класс, который добавляет несколько строк поиска и пару событий:

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");
3 голосов
/ 21 марта 2009

Я бы очень просто:

  • Открыть файл для чтения / записи
  • Чтение / поиск по нему до начала строки, которую вы хотите удалить
  • Установить указатель записи на текущий указатель чтения
  • Прочитайте до конца строки, которую мы удаляем, и пропустите разделители новой строки (считая количество символов по ходу, мы назовем это nline)
  • Чтение за байтом и запись каждого байта в файл
  • Когда закончите, обрежьте файл до (orig_length - nline).
2 голосов
/ 19 марта 2015

Я написал метод удаления строк из файлов.

Эта программа использует 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());
    }
}
0 голосов
/ 01 июня 2015

Почему нельзя использовать это? Сначала создайте массив:

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

Затем найдите строку, которую нужно удалить, и замените ее на "":

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

Готово!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...