Условно убрать последнюю строку из текстового файла - PullRequest
2 голосов
/ 22 мая 2010

Я вчера написал это на SO, и я получил ответ, который отлично работает, но мне нужно изменить его, и я не знаю как.

Вот мой оригинальный вопрос :


Мне нужно убрать последнюю строку из текстового файла.Я знаю, как открывать и сохранять текстовые файлы в C #, но как бы обрезать последнюю строку текстового файла?

Текстовый файл всегда будет иметь разные размеры (некоторые имеют 80 строк, некоторые имеют 20).

Как это сделать?


Вот код, который кто-то дал мне, чтобы сделать это (который прекрасно работает)

//Delete the last line from the file.  This line could be 8174, 10000, or anything.  This is from SO
string tempfile = @"C:\junk_temp.txt";

using (StreamReader reader2 = new StreamReader(newfilename))
{
    using (StreamWriter writer2 = new StreamWriter(tempfile))
    {
        string line = reader2.ReadLine();

        while (!reader2.EndOfStream)
        {
            writer2.WriteLine(line);
            line = reader2.ReadLine();
        } // by reading ahead, will not write last line to file 
    }
}

File.Delete(newfilename);
File.Move(tempfile, newfilename);
File.Delete(tempfile);

Как бы изменить это, чтобы удалить только последнюю строку текстового файла, если это строка из 4 или 5 цифр (например, 8001 или 99999).

Если это что-то иное, например,%, тогда я не хочу удалять последнюю строку.

Может кто-нибудь изменить вышеприведенный код, чтобы сделать это для меня?

Ответы [ 7 ]

3 голосов
/ 22 мая 2010

Чтобы сохранить ту же логику, что и в текущем коде, вы можете сделать следующее

        //Delete the last line from the file.  This line could be 8174, 10000, or anything.  This is from SO 
        string tempfile = @"C:\junk_temp.txt"; 

        using (StreamReader reader2 = new StreamReader(newfilename)) 
        { 
            using (StreamWriter writer2 = new StreamWriter(tempfile)) 
            { 
                string line = reader2.ReadLine(); 

                while (!reader2.EndOfStream) 
                { 
                    writer2.WriteLine(line); 
                    line = reader2.ReadLine(); 
                } // by reading ahead, will not write last line to file  

                // If the last line read does not match your condition
                // we write it to the new file
                if (!Regex.IsMatch(line, @"^\d{4,5}$"))
                {
                    writer2.WriteLine(line); 
                } 
            } 
        } 

        File.Delete(newfilename); 
        File.Move(tempfile, newfilename); 
        File.Delete(tempfile);
0 голосов
/ 22 мая 2010
        string tempfile = @"C:\junk_temp.txt";

        using (StreamReader reader2 = new StreamReader(newfilename))
        {
            using (StreamWriter writer2 = new StreamWriter(tempfile))
            {
                string line = reader2.ReadLine();

                while (!reader2.EndOfStream)
                {
                    writer2.WriteLine(line);
                    line = reader2.ReadLine();
                } // by reading ahead, will not write last line to file 
                int result=0;
                if (Int32.TryParse(s, out result) )
                {
                    if (s.Length != 4 || s.Length != 5)
                       writer2.WriteLine(line);
                }
            }
        }

        File.Delete(newfilename);
        File.Move(tempfile, newfilename);
        File.Delete(tempfile);
0 голосов
/ 22 мая 2010

Я не хочу "модифицировать код" напрямую для вас, но я дам вам указатель.

string line = reader2.ReadLine();

while (!reader2.EndOfStream)
{
    writer2.WriteLine(line);
    line = reader2.ReadLine();
} // by reading ahead, will not write last line to file 

Сразу после последней фигурной скобки } в этом коде у вас есть последняя строка файла в переменной line. В вашем текущем коде эта строка отбрасывается. Я бы предложил вам вставить здесь выражение «если», сравнивая эту последнюю строку с вашими критериями. Вы можете использовать для этого регулярное выражение, например, ^[0-9]{4,5}$ должно подойти.

Если критерии соблюдены, просто наберите writer2.WriteLine(line); еще раз для последней строки.

0 голосов
/ 22 мая 2010

Измените while на:

while (!reader2.EndOfStream)
{
    string line = reader2.ReadLine();
    if (reader2.EndOfStream && (CheckIfNeedToDeleteLine(line) == false))
    {
        writer2.WriteLine(line);
    }
}

Вам нужно будет реализовать CheckIfNeedToDeleteLine(line).

bool CheckIfNeedToDeleteLine(string line)
{
    int digit = 0;
    return (((line.Length == 4) || (line.Length == 5)) &&
        (int.TryParse(line, out digit)))     
}

Regex реализация CheckIfNeedToDeleteLine:

bool CheckIfNeedToDeleteLine(string line)
{
    return Regex.IsMatch(line, @"^\d{4,5}$"); 
}

Нет идеи, которая более эффективна, но это на самом деле не имеет значения, поскольку это произойдет только на последней итерации из-за порядка оператора if.

0 голосов
/ 22 мая 2010

Добавьте это после окончания цикла while:

if (!Regex.IsMatch(line, @"^\d{4,5}$"))
    writer2.WriteLine(line);
0 голосов
/ 22 мая 2010

Создайте RegEx, который соответствует строке из 4 или 5 цифр, и отфильтруйте удаление по ней. В Интернете есть множество хороших сайтов для практики / обучения C # RegEx.

0 голосов
/ 22 мая 2010

Вы должны будете поставить условную проверку после

line = reader2.ReadLine();

для проверки EndOfStream и, если это правда, ваша условная проверка для строки (либо RegEx, либо line.Length == 5).

...