Как прочитать указанную строку в текстовом файле? - PullRequest
52 голосов
/ 12 августа 2009

Учитывая текстовый файл, как бы я прочитал произвольную строку и ничего больше в файле?

Скажем, у меня есть файл test.txt.Как бы я прочитал строку номер 15 в файле?

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

Есть ли способы ТОЛЬКО прочитать определенную строку текстового файла и сохранить результат в виде строки?

Спасибо за ваши ответы: Файл структурирован KINDA.У него 25 информационных строк, а затем X строк чисел, но строка 17 из первых 25 имеет значение X .

Но тогда есть 1 пустая строкаи он повторяется как вторая запись в файле, и X может иметь различное значение для каждой записи.

Я хочу прочитать и сохранить первые 25 строк какнезависимые значения и затем сохраните следующие X (обычно около 250) строк в виде массива.Затем я собираюсь сохранить его в базе данных SQL и повторять с NEXT-записью, пока не достигну Y -ой записи (количество записей в файле находится в строке 3)

РЕДАКТИРОВАТЬ 2 : Хорошо, я думаю, что я нашел решение, основанное на комбинации ваших ответов.

Я прочитаю первые 25 строк и сохраню их какмассив.Я скопирую соответствующее содержимое массива в локальные переменные, затем удалю первые 25 строк.Затем я могу использовать эту информацию, чтобы сохранить следующие X строки (значение элемента 13 в массиве) в виде массива, сериализовать его, сохранить в базе данных, а затем удалить только что прочитанные строки.

Я мог бы затем повторить процесс для каждой последующей записи.

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

Ответы [ 14 ]

94 голосов
/ 12 августа 2009

.NET 4.0 edit

Начиная с .NET 4.0, можно напрямую обращаться к одной строке файла. Например, для доступа к строке 15:

string line = File.ReadLines(FileName).Skip(14).Take(1).First();

Это вернет только необходимую строку


Поскольку вы не можете предсказать местоположение (не так ли?) I-й строки в файле, вам также придется прочитать все предыдущие строки. Если номер строки мал, это может быть более эффективным, чем метод ReadAllLines.

string GetLine(string fileName, int line)
{
   using (var sr = new StreamReader(fileName)) {
       for (int i = 1; i < line; i++)
          sr.ReadLine();
       return sr.ReadLine();
   }
}
12 голосов
/ 12 августа 2009

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

using( Stream stream = File.Open(fileName, FileMode.Open) )
{
    stream.Seek(bytesPerLine * (myLine - 1), SeekOrigin.Begin);
    using( StreamReader reader = new StreamReader(stream) )
    {
        string line = reader.ReadLine();
    }
}

В качестве альтернативы вы можете просто использовать StreamReader для чтения строк, пока не найдете нужный. Это медленнее, но все же лучше, чем чтение каждой строки.

using( Stream stream = File.Open(fileName, FileMode.Open) )
{
    using( StreamReader reader = new StreamReader(fileStream) )
    {
        string line = null;
        for( int i = 0; i < myLineNumber; ++i )
        {
            line = reader.ReadLine();
        }
    }
}
4 голосов
/ 12 августа 2009

Нет, к сожалению, нет. На необработанном уровне файлы не работают на основе номера строки. Вместо этого они работают на основе позиции / смещения. Корневая файловая система не имеет понятия линий. Это концепция, добавленная компонентами более высокого уровня.

Так что нет никакой возможности узнать операционную систему, пожалуйста, откройте файл в строке бла. Вместо этого вы должны открыть файл и пропустить подсчет новых строк, пока не пройдете указанное число. Затем сохраните следующий набор байтов в массиве, пока не достигнете следующей новой строки.

3 голосов
/ 12 августа 2009

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

Edit:

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

2 голосов
/ 12 июля 2013

Читайте пять строк каждый раз, просто вставьте свое утверждение в утверждение if, вот оно

        String str1 = @"C:\Users\TEMP\Desktop\StaN.txt";   

        System.IO.StreamReader file = new System.IO.StreamReader(str1);

        line = file.ReadLine();

        Int32 ctn=0;

        try
        {

            while ((line = file.ReadLine()) != null)
            {

                    if (Counter == ctn)
                    {
                        MessageBox.Show("I am here");
                        ctn=ctn+5;
                        continue;
                    }
                    else
                    {
                        Counter++;
                        //MessageBox.Show(Counter.ToString());
                        MessageBox.Show(line.ToString());
                    } 
                }

            file.Close();
        }
        catch (Exception er)
        {

        }
2 голосов
/ 12 августа 2009

Как сказал Мерадад, вы не можете просто перейти к n-й строке, не прочитав файл. Однако вам не нужно хранить весь файл в памяти - просто удалите ненужные данные.

string line;
using (StreamReader sr = new StreamReader(path))
    for (int i = 0; i<15; i++)
    {
       line = sr.ReadLine();
       if (line==null) break; // there are less than 15 lines in the file
    }
1 голос
/ 12 августа 2009

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

Если строки имеют переменную длину, ваши параметры более ограничены.

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

Если это файл, который вы будете хранить и будете читать не из записи, вы можете создать собственный индексный файл, содержащий начальные позиции каждой строки. Затем используйте этот индекс, чтобы получить свою позицию поиска. Процесс создания индексного файла является ресурсоемким. Каждый раз, когда вы добавляете новую строку в файл, вам нужно будет обновить индекс, чтобы обслуживание стало нетривиальной проблемой.

0 голосов
/ 01 мая 2018

Вариация. Выдает ошибку, если номер строки превышает количество строк.

string GetLine(string fileName, int lineNum)
{
    using (StreamReader sr = new StreamReader(fileName))
    {
        string line;
        int count = 1;
        while ((line = sr.ReadLine()) != null)
        {
            if(count == lineNum)
            {
                return line;
            }
            count++;
        }
    }
    return "line number is bigger than number of lines";  
}
0 голосов
/ 19 ноября 2017

Испытано и проверено. Это так просто:

string line = File.ReadLines(filePath).ElementAt(actualLineNumber - 1);

Пока у вас есть текстовый файл, это должно работать. Позже, в зависимости от того, какие данные вы ожидаете прочитать, вы можете соответствующим образом привести строку и использовать ее.

0 голосов
/ 11 апреля 2015
        if (File.Exists(fpath))
        {

            var data = File.ReadLines(fpath);
            Console.WriteLine(data.ToArray()[14]);
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...