【问题标题】:Attempting to read a txt file - locking up尝试读取 txt 文件 - 锁定
【发布时间】:2014-02-27 21:05:16
【问题描述】:

我正在尝试读取文本文件的某个部分。文本如下所示:

[HRZones]
195
175
156

0

[SwapTimes]

[Trip]
474
0
6616
-223


[HRData]
84  182 87  -222    129 4139
84  182 87  -222    129 4139
88  179 86  -222    133 3640
95  185 92  -222    136 3393
103 193 91  -222    123 4666
107 196 94  -222    125 5684
107 198 96  -222    128 4919
109 197 95  -222    131 4926
110 198 96  -222    134 4655
111 196 95  -222    126 4154

该文件实际上在 [HRData] 部分下包含更多行。

我正在尝试使用以下代码获取 [HRData}。可悲的是,这会锁定程序;断点显示这发生在第一个 while 循环中.. 几乎就像什么都看不到?

 private void readFile()
    {
        //read the hrm file and split values
        try
        {
            using (StreamReader sr = new StreamReader(file_name))
            {
                string line;

                while ((line = sr.ReadLine()) != "[HRData]")
                {
                    line = sr.ReadLine(); // FAILS HERE.. 
                }

                while((line = sr.ReadLine()) != null)
                {
                    string split = line;
                    string[] values = split.Split('\t');
                    foreach (String value in values)
                    {
                        hrdata[i, j] = int.Parse(value);
                        i++;
                        if (i > 5)
                        {
                            i = 0;
                            j++;
                        }
                    }
                }
            }
        }

文件名是从先前的检查中传递的,数据看起来不错。

【问题讨论】:

  • 您在将其中一行与[HRData] 进行比较之前一次读取两行...您需要摆脱循环内的line = sr.ReadLine();,这样您就只能一次读取一行时间。
  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。

标签: c# split streamreader readline


【解决方案1】:

在这里您检查一行并跳过下一行。避免第二个ReadLine

while ((line = sr.ReadLine()) != "[HRData]")
{
    line = sr.ReadLine(); // FAILS HERE.. 
}

【讨论】:

    【解决方案2】:

    检查 EOF 和 Trim() 以使文本相等起作用。以下应该工作

                while (!sr.EndOfStream)
                {
                    var line = sr.ReadLine();
                    if (!string.IsNullOrWhiteSpace(line) && line.Trim() == "[HRData]")
                    {
                        break;
                    }
                }
    
                while (!sr.EndOfStream)
                {
                    string split = sr.ReadLine();
                    string[] values = split.Split('\t');
    
                    foreach (String value in values)
                    {
                        hrdata[i, j] = int.Parse(value);
                        i++;
                        if (i > 5)
                        {
                            i = 0;
                            j++;
                        }
                    }
                }
    

    【讨论】:

      【解决方案3】:

      正如一些人已经指出的那样,您在循环条件期间读取一行,然后在循环体中再次读取,因此这可能会起作用或失败,具体取决于 [HRData] 出现在奇数行还是偶数行文件。

      while 循环重写为for 循环:

      for (var line = sr.ReadLine();
           line != null && line != "[HRData]");
           line = sr.ReadLine()) { /* NOP */ }
      

      如果你负担得起使用 LINQ,那么下面的内容就更简单了,不需要任何脑力操:

      foreach (var line in File.ReadLines().SkipWhile(s => s != "[HRData]")) {
          // ...
      }
      

      【讨论】:

        【解决方案4】:

        我注意到的两件事:

        1) 您没有检查[HRData]“标签”。您检查该行是否不是标记且不为空。

        2) 我认为你的 while 循环作为一个整体不知道在文件末尾停止读取。

        【讨论】:

          【解决方案5】:

          使用该循环,您可能会跳过包含搜索文本的行,因为您阅读了两次但只测试了一次

           string line = sr.ReadLine();
           while (line != null && line != "[HRData]")
           {
               line = sr.ReadLine();
           }
          

          如果文件恰好在循环之前多出一行,它可能会起作用,但错误仍然存​​在

          【讨论】:

          • 非常感谢 - 只要允许我就会接受 :)
          猜你喜欢
          • 2021-04-18
          • 2021-06-25
          • 1970-01-01
          • 1970-01-01
          • 2018-04-19
          • 1970-01-01
          • 2013-02-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多