Есть ли способ игнорировать чтение в определенных строках в текстовом файле? - PullRequest
2 голосов
/ 15 сентября 2010

Я пытаюсь прочитать текстовый файл в приложении c #, но я не хочу читать первые две строки или последнюю строку. В файле 8 строк, поэтому я просто хочу прочитать в строках 3, 4, 5, 6 и 7. Есть ли способ сделать это?

файл примера

USE [Другая база данных Шелли]
CREATE TABLE db.exmpcustomers (
fName varchar (100) NULL,
Имя varchar (100) NULL,
dateOfBirth date NULL,
houseNumber int NULL,
streetName varchar (100) NULL
) ВКЛ [ПЕРВИЧНЫЙ]

РЕДАКТИРОВАТЬ

Итак, я внедрил ответ Callum Rogers в свой код, и по какой-то причине он работает с моим отредактированным текстовым файлом (я создал текстовый файл со строками, которые я не хотел использовать опущенными), и он делает точно что это должно, но всякий раз, когда я пытаюсь сделать это с оригинальным текстовым файлом (выше), он выдает исключение. Я отображаю эту информацию в DataGrid и думаю, что именно здесь выдается исключение.

Есть идеи?

Ответы [ 7 ]

9 голосов
/ 15 сентября 2010

Ответ Роджерса хорош, я просто предоставляю другой способ сделать это.Попробуйте,

List<string> list = new List<string>();
using (StreamReader reader = new StreamReader(FilePath))
{
    string text = "";
    while ((text = reader.ReadLine()) != null)
    {
        list.Add(text);
    }
    list.RemoveAt(0);
    list.RemoveAt(0);
 }

Надеюсь, это поможет

8 голосов
/ 15 сентября 2010

Почему вы хотите игнорировать ровно первые две и последнюю строку?

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

Иногда жесткое кодирование «магических» чисел не такая хорошая идея.Что, если необходимо изменить формат файла, чтобы он содержал 3 строки заголовка?

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

Отредактируйте, теперь, когда вы предоставили пример вашего файла: Для вашего случая я бы определенно не используйте жестко закодированный подход чисел.Что если однажды SQL-оператор будет содержать другое поле или он появится в одной строке вместо 8 строк?

Мое предложение: прочитать всю строку сразу, а затем проанализировать ее.Самый безопасный способ - использовать грамматику , но если вы предполагаете, что оператор SQL никогда не будет более сложным, вы можете использовать регулярное выражение (все же намного лучше, чем использование номеров строк и т. Д.):

string content = File.ReadAllText(filename);
Regex r = new Regex(@"CREATE TABLE [^\(]+\((.*)\) ON");
string whatYouWant = r.Match(content).Groups[0].Value;
8 голосов
/ 15 сентября 2010

Почему бы просто не использовать File.ReadAllLines(), а затем удалить первые 2 строки и последнюю строку? При таком маленьком файле разницы в скорости не будет заметно.

string[] allLines = File.ReadAllLines("file.ext");
string[] linesWanted = new string[allLines.Length-3];
Array.Copy(allLines, 2, linesWanted, 0, allLines.Length-3);
2 голосов
/ 15 сентября 2010

Если у вас есть TextReader объект, оборачивающий файловый поток, вы можете просто вызвать ReadLine () два раза.

StreamReader наследуется от TextReader, который является абстрактным.

Пример без дурака:

using (var fs = new FileStream("blah", FileMode.Open))
using (var reader = new StreamReader(fs))
{
    reader.ReadLine();
    reader.ReadLine();

    // Do stuff.
}
0 голосов
/ 15 сентября 2010

Как насчет общего решения?

Для меня первым шагом является перечисление по строкам файла (уже предоставлено ReadAllLines,но это приводит к снижению производительности из-за заполнения всего массива string[], а также ReadLines, но это доступно только с .NET 4.0).

Реализация этого довольно тривиальна:

public static IEnumerable<string> EnumerateLines(this FileInfo file)
{
    using (var reader = file.OpenText())
    {
        while (!reader.EndOfStream)
        {
            yield return reader.ReadLine();
        }
    }
}

Следующим шагом будет просто пропустить первые две строки этой перечислимой последовательности.Это просто с использованием метода расширения Skip.

Последний шаг - игнорирование последней строки перечислимой последовательности.Вот один способ, которым вы могли бы реализовать это:

public static IEnumerable<T> IgnoreLast<T>(this IEnumerable<T> source, int ignoreCount)
{
    if (ignoreCount < 0)
    {
        throw new ArgumentOutOfRangeException("ignoreCount");
    }

    var buffer = new Queue<T>();
    foreach (T value in source)
    {
        if (buffer.Count < ignoreCount)
        {
            buffer.Enqueue(value);
            continue;
        }

        T buffered = buffer.Dequeue();

        buffer.Enqueue(value);

        yield return buffered;
    }
}

ОК, тогда.Собрав все это вместе, мы имеем:

var file = new FileInfo(@"path\to\file.txt");
var lines = file.EnumerateLines().Skip(2).IgnoreLast(1);

Тестовый ввод (содержимое файла):

This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is line number 5.
This is line number 6.
This is line number 7.
This is line number 8.
This is line number 9.
This is line number 10.

Вывод (из Skip(2).IgnoreLast(1)):

This is line number 3.
This is line number 4.
This is line number 5.
This is line number 6.
This is line number 7.
This is line number 8.
This is line number 9.
0 голосов
/ 15 сентября 2010
string filepath = @"C:\whatever.txt";
using (StreamReader rdr = new StreamReader(filepath))
{
    rdr.ReadLine();  // ignore 1st line
    rdr.ReadLine();  // ignore 2nd line
    string fileContents = "";
    while (true)
    {
        string line = rdr.ReadLine();
        if (rdr.EndOfStream)
            break;  // finish without processing last line
        fileContents += line + @"\r\n";
    }
    Console.WriteLine(fileContents);
}
0 голосов
/ 15 сентября 2010

Вы можете сделать это:

var valid = new int[] { 3, 4, 5, 6, 7 };
var lines = File.ReadAllLines("file.txt").
    Where((line, index) => valid.Contains(index + 1));

Или наоборот:

var invalid = new int[] { 1, 2, 8 };
var lines = File.ReadAllLines("file.txt").
    Where((line, index) => !invalid.Contains(index + 1));

Если вы ищете общий способ удалить последние и первые 2, вы можетеиспользуйте это:

var allLines = File.ReadAllLines("file.txt");
var lines = allLines
  .Take(allLines.Length - 1)
  .Skip(2);

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

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