2009-10-03 6 views
4

Для проекта, который я делаю, одна из вещей, которую я должен сделать, это удалить первые строки X строк открытого текстового файла. Я говорю X, потому что мне нужно будет выполнять эту процедуру несколько раз и каждый раз, строки для удаления будут разными, но они всегда будут начинаться с начала, удалять первый X, а затем выводить результаты на тот же файл.Как удалить первые строки «X» текстового файла?

Я имею в виду сделать что-то вроде этого, что я кусочки из других руководств и примеров, которые я прочитал:

String line = null; 

String tempFile = Path.GetTempFileName(); 
String filePath = openFileDialog.FileName; 

int line_number = 0; 
int lines_to_delete = 25; 

using (StreamReader reader = new StreamReader(originalFile)) { 
    using (StreamWriter writer = new StreamWriter(tempFile)) { 
     while ((line = reader.ReadLine()) != null) { 
      line_number++; 

      if (line_number <= lines_to_delete) 
       continue; 

      writer.WriteLine(line); 
     } 
    } 
} 

if (File.Exists(tempFile)) { 
    File.Delete(originalFile); 
    File.Move(tempFile, originalFile); 
} 

Но я не знаю, если это будет работать из-за мелочи, как номера строк начиная с строки 0 или еще чего ... Кроме того, я не знаю, хороший ли код с точки зрения эффективности и формы.

Спасибо, кучка.

ответ

6

Все в порядке, и не похоже, что у вас будут проблемы, которые вы боитесь. Однако более компактный подход был бы обеспечен двумя отдельными циклами - один, чтобы просто подсчитать первые X строк из входного файла (и не делать ничего другого), отдельный, чтобы просто скопировать другие строки с ввода на вывод. Т.е., вместо вашего единственного while цикла, есть ...:

while ((line = reader.ReadLine()) != null) { 
     line_number++; 

     if (line_number > lines_to_delete) 
      break; 
    } 

    while ((line = reader.ReadLine()) != null) { 
     writer.WriteLine(line); 
    } 
+0

Это работает, потому что, когда я снова сделать reader.ReadLine(), он возобновляет чтение, где она была прервана, не так ли? Если бы я хотел сделать другого читателя под названием «читатель» (так как это было бы в более крупном цикле, который повторял бы этот процесс несколько раз), мне просто нужно было бы закрыть «читателя», а затем, когда я сделаю еще один, он начнет назад с начала файла, правильно? – ankushg

+0

@Unk, да, на оба вопроса в этом комментарии. –

+0

Спасибо! – ankushg

0

Вы можете прочитать файл в массив строк, игнорировать первые элементы, и писать остальное обратно.

Недостатком этого подхода является то, что он будет потреблять размер файла в памяти. Ваш подход (хотя довольно нечитаемый, без обид) не имеет этой проблемы с памятью. Хотя если файлы не слишком большие, не должно быть причин беспокоиться об использовании памяти.

Пример:

string[] lines = System.IO.File.ReadAllLines("YourFile.txt").Skip(10).ToArray(); 
System.IO.File.WriteAllLines("OutFile.txt", lines); 
+0

Да, основная проблема заключается в том, что файл EXTREMELY большой, а компьютер, на котором будет работать программа, не является точно первоклассным. Я уже использую множество массивов для вещей, поэтому я пошел с моим подходом к этому; читая его и записывая на месте. Спасибо за вашу помощь, так или иначе. – ankushg

+0

Ой, мой плохой, забудьте ToArray() –

8

Мне нравится коротка ...

File.WriteAllLines(
    fileName, 
    File.ReadAllLines(fileName).Skip(numberLinesToSkip).ToArray()); 
+0

Хорошее чистое решение. Это вызовет проблемы, если исходный файл слишком велик, так как он считывает весь файл в память. – LukeH

+0

Да, это действительно чисто, но, как я упоминал в сообщении Чарли, файл чрезвычайно велик, и это приложение не будет работать на мощной машине ... Спасибо, хотя; Я не знал обо всех тех методах, которые вы использовали, и я изучил некоторые новые вещи! – ankushg

2

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

Чуть менее многословным версия о том, что у вас уже есть:

using (StreamReader reader = new StreamReader(originalFile)) 
using (StreamWriter writer = new StreamWriter(tempFile)) 
{ 
    while(lines_to_delete-- > 0) 
     reader.ReadLine(); 
    while ((line = reader.ReadLine()) != null) 
     writer.WriteLine(line); 
} 
+0

Спасибо за ваш вклад! – ankushg

Смежные вопросы