2012-02-28 3 views
0

Цель кода - найти часть строки (из одного документа) в длинном списке строк (другой документ) и вернуть результаты в список.Inner While Loop запускается только один раз

У меня есть два цикла while, один вложен в другой. Внешний цикл считывает каждую строку этого документа, а внутренний считывает каждый цикл своего документа. По какой-то причине внутренний пока работает только один раз (для первой итерации внешнего цикла). Можете ли вы объяснить, почему и как я могу это исправить? Кажется, он только читает все строки один раз, а затем не читает их снова ... Мне нужно, чтобы внутренний цикл читался по строкам каждый раз, когда выполняется внешний цикл.

Вот мой код.

private static void getGUIDAndType() 
    { 
     try 
     { 
      Console.WriteLine("Begin."); 

      String dbFilePath = @"C:\WindowsApps\CRM\crm_interface\data\"; 
      StreamReader dbsr = new StreamReader(dbFilePath + "newdbcontents.txt"); 
      List<string> dblines = new List<string>(); 

      String newDataPath = @"C:\WindowsApps\CRM\crm_interface\data\"; 
      StreamReader nsr = new StreamReader(newDataPath + "HolidayList1.txt"); 
      List<string> new1 = new List<string>(); 

      string dbline; 
      string newline; 

      Program prog = new Program(); 

      while ((dbline = dbsr.ReadLine()) != null) 
      { 
       while ((newline = nsr.ReadLine()) != null) 
       { 
        newline = newline.Trim(); 
        if (dbline.IndexOf(newline) != -1) 
        {//if found... get all info for now 
         Console.WriteLine("FOUND: " + newline); 
         System.Threading.Thread.Sleep(1000); 
         new1.Add(newline); 
        } 
        else 
        {//the first line of db does not contain this line... 
         //go to next newline. 
         Console.WriteLine("Lines do not match - continuing"); 
         continue; 
        } 
       } 
       nsr.Close(); 
       Console.WriteLine("should be run as many times as there are dblines"); 
       Console.WriteLine(newline); 
       System.Threading.Thread.Sleep(5000); 
       //continue; 
      } 

      Console.WriteLine("Writing to dbc2.txt"); 
      System.IO.File.WriteAllLines(@"C:\WindowsApps\CRM\crm_interface\data\dbc2.txt", new1.ToArray()); 
      Console.WriteLine("Finished. Press ENTER to continue."); 

      Console.WriteLine("End."); 
      Console.ReadLine(); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Error: " + ex); 
      Console.ReadLine(); 
     } 
    } 

Я попытался установить внутренний цикл как метод, но когда я ссылаться на dbline в методе я получаю ссылку на объект исключения на этой линии: if (dbline.IndexOf(newline) != -1). На самом деле не потратили много времени, пытаясь исправить это и вернулись к вложенным циклам; но если бы я использовал этот метод, я не думаю, что мой результат будет другим.

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

Спасибо.

+1

Насколько велики файлы? Я бы предложил отказаться от StreamReader и просто использовать 'File.ReadAllLines' http://msdn.microsoft.com/en-us/library/system.io.file.readalllines.aspx – asawyer

ответ

3

Для каждой итерации внешнего цикла, необходимо перемотать StreamReader внутреннего контура к началу файла:

while ((dbline = dbsr.ReadLine()) != null) 
    { 
    // Reset 
    nsr.BaseStream.Position = 0; 
    nsr.DiscardBufferedData(); 

    while ((newline = nsr.ReadLine()) != null) 
    { 
     ..... 
    } 
    nsr.Close(); // remove that 

EDIT согласно комментарии:

Вы также необходимо удалить Close() StreamReader после внутреннего цикла, переместить его после внешнего цикла.

+1

И удалить Close() после внутреннего петля. –

+0

'StreamReader' не имеет свойства' Position' ... его необходимо установить на основе 'Stream'. – Rob

+0

@robjb: см. Править – thumbmunkeys

3

Ваш внутренний цикл использует файл. Вернитесь к началу.

1

Поскольку ваш while цикла завершение без break или return заявления, это означает, что это условие цикла оценка ложь:

(newline = nsr.ReadLine()) != null 

То есть, nsr.Readline() возвращается null, потому что вы попали окончание срока файла ,

Если вы действительно собираетесь читать строки несколько раз из nsr, вы можете обратиться к началу путем сброса позиции на подстилающей Stream и отбрасывая StreamReader «s буфера:

nsr.BaseStream.Position = 0; 
nsr.DiscardBufferedData(); 
Смежные вопросы