Исключить последнюю строку из StreamReader в С#

Я сохраняю некоторые данные DataGridView в текстовый файл (для данных я имею в виду содержимое каждой ячейки), а в последней строке файла TXT я сохраняю количество строк dataGridView с помощью "- " в начале строки.

Теперь я могу идеально читать свои данные в своем DVG, но как я могу исключить последнюю строку, содержащую количество строк, а также использовать ее для чтения сохраненного int?

Код, который я использую для чтения данных в DVG:

void LoadDVGData()
    {
        StreamReader sr = new StreamReader(open.FileName);
        foreach (DataGridViewRow row in editDGV.Rows)
        {
            foreach (DataGridViewCell cell in row.Cells)
            {
                string content = sr.ReadLine();
                cell.Value = content;
            }
        }
        sr.Close();
    }

Заранее спасибо. - ЦКБ


person ChrisCreateBoss    schedule 10.06.2015    source источник
comment
Что у вас есть на данный момент для решения этой проблемы?   -  person xxbbcc    schedule 10.06.2015
comment
С уважением, я не знаю, как начать.   -  person ChrisCreateBoss    schedule 10.06.2015
comment
Вы сказали, что можете прочитать свои данные в DGV - исключение последней строки - это всего лишь один дополнительный шаг. Можете ли вы показать свой код для загрузки данных?   -  person xxbbcc    schedule 10.06.2015
comment
Хорошо, я обновлю вопрос с кодом dataRead.   -  person ChrisCreateBoss    schedule 10.06.2015
comment
Что, если в вашем файле закончатся строки до того, как вы просмотрите все свои editDGV.Rows.Cells?   -  person Dour High Arch    schedule 10.06.2015
comment
Как насчет вызова File.ReadAllLines, а затем зацикливания for (int i=0;i<lines.Count-2;i++)?   -  person vesan    schedule 10.06.2015
comment
@vesan Это работает для небольших файлов. Учитывая, что это DGV, он может работать нормально.   -  person xxbbcc    schedule 10.06.2015
comment
Я думаю, вам было бы намного проще, если бы счет был первой строкой файла, а не последней.   -  person vesan    schedule 10.06.2015


Ответы (2)


Вам просто нужно поддерживать один маркер просмотра вперед, чтобы вы могли ответить на вопрос: «Это последняя строка?» (если у вас есть текущая строка, но нет следующей строки, вы находитесь на последней строке.

Вот один из подходов, который, вероятно, настолько прост, насколько это возможно:

void LoadDVGData()
{
  using ( StreamReader sr = new StreamReader(open.FileName) )
  {
    string currentLine = sr.ReadLine() ;
    string nextLine    = sr.ReadLine() ;

    foreach (DataGridViewRow row in editDGV.Rows)
    {
      foreach (DataGridViewCell cell in row.Cells)
      {
        if ( currentLine == null ) throw new InvalidOperationException("Hmph. We seem to have run out of input data");

        cell.Value = currentLine ;

        currentLine = nextLine ;
        nextLine = sr.ReadLine() ;

      } //end cols loop
    } // end rows loop

  } // end using block

  return;
}
person Nicholas Carey    schedule 10.06.2015

Я предполагаю, что sr - это StreamReader, который читает ваш текстовый файл - вы должны обернуть его в блок using или try..finally, чтобы обеспечить правильную очистку в случае ошибок.

Ваша текущая настройка не очень хорошо работает для случаев, когда текстовый файл не соответствует количеству строк/ячеек, которые у вас есть в DataGridView (DGV): вы пытаетесь прочитать значение из файла для каждой ячейки, и если неправильно указан файл, вы можете попытаться прочитать его дальше конца. У вас должно быть больше обработки ошибок вокруг этого кода, потому что при чтении файла могут возникнуть различные проблемные места: слишком мало строк, слишком мало ячеек для строки, недопустимое значение для конкретной ячейки и т. д.

Ваша установка не очень хорошо поддается обработке. Если вы управляете форматом текстового файла, я бы рекомендовал изменить формат так, чтобы самая первая строка была счетчиком, а затем каждая строка в текстовом файле описывала полную строку для DGV, используя TAB в качестве разделителя. Было бы гораздо проще загрузить такой файл. (Вы даже можете указать количество строк и количество столбцов в первой строке, чтобы получить еще больше информации о данных; у вас никогда не будет слишком много метаданных о входных данных.)

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

3{TAB}5
R1C1{TAB}R1C2{TAB}R1C3{TAB}R1C4{TAB}R1C5{CRLF}
R2C1{TAB}R2C2{TAB}R2C3{TAB}R2C4{TAB}R2C5{CRLF}
R3C1{TAB}R3C2{TAB}R3C3{TAB}R3C4{TAB}R3C5{CRLF}

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

Изменить:

Как прокомментировал @vesan вопрос, если ваш входной файл невелик, вы можете просто вызвать File.ReadAllLines(), чтобы получить все строки в файле string[]. Тогда это тривиально обработать. Однако использование более удобного формата файла будет работать для любого размера файла. Чтение всех строк предполагает, что входной файл невелик.

Редактировать 2:

Например (для краткости обработка ошибок опущена):

var sLines = File.ReadAllLines ( open.FileName );
var nRowCount = int.Parse ( sLines[sLines.Length - 1] );
var nIndex = 0;

foreach (DataGridViewRow row in editDGV.Rows)
{
    foreach (DataGridViewCell cell in row.Cells)
    {
        cell.Value = sLines[nIndex];
        nIndex++;
    }
}

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

person xxbbcc    schedule 10.06.2015
comment
Да, я знаю, что если я выберу неправильный файл, мой DVG будет испорчен, я просто использовал .txt для теста, но позже я изменю формат, может быть, на пользовательский. Если бы я прочитал файл дважды, как я могу игнорировать последнюю строку при чтении в DVG?? - person ChrisCreateBoss; 10.06.2015
comment
@ChrisCreateBoss Если вы измените формат файла, у вас будет количество строк / столбцов в первой строке - вы просто читаете одну строку, а все остальные строки являются данными. Тогда ваша проблема намного проще. На самом деле, если вы можете свободно изменять формат файла, я бы просто выбрал XML (он редактируется человеком, но имеет структуру) или полный двоичный файл (не редактируемый человеком, но очень простой для чтения/записи и обнаружения ошибок). Если вы управляете форматом входного файла, просто выберите формат, который содержит все данные и удобен в обращении — вы можете выбрать любой макет, который вам нравится. - person xxbbcc; 10.06.2015
comment
@ChrisCreateBoss Извините, я неправильно прочитал ваш комментарий - если вы прочитаете файл дважды (не меняя формат), то сначала вы прочитаете последнюю строку - это даст вам количество строк. После этого вы читаете так много строк из файла - если файл правильный, вы должны закончить чтение, прежде чем когда-либо достигнете последней строки на 2-м проходе. - person xxbbcc; 10.06.2015
comment
@ChrisCreateBoss Если вы можете изменить формат файла, сделайте это как можно раньше - нет смысла реализовывать какую-то сложную логику для чтения данных, когда вы можете сделать это только один раз и проще. - person xxbbcc; 10.06.2015
comment
Да, это небольшой файл, примерно 10 или 20 строк данных. - person ChrisCreateBoss; 10.06.2015
comment
@ChrisCreateBoss Если это гарантировано, просто используйте File.ReadAllText() и возьмите последний элемент массива как количество строк. - person xxbbcc; 10.06.2015