在文本文件中查找数据行

时间:2017-01-01 03:11:09

标签: c# file

我有一个文本文件(它实际上是一个Intel Hex文件,但数据是ASCII文本),我无法找到一种方法来查找零数据的起始行和结束行。

文件将从数据行开始,然后可能有几行为零,然后再次为数据。我要做的是找到最后一组零的位置。

作为示例,该文件可能包含:

:1234567890
:0987654321
:0000000000
:0000000000
:ABCDEFABCD
:DCBAFEDCBA
:0000000000
:0000000000
:0000000000
:9999999999

对于这个文件,我希望将第7行作为起始行,将第9行作为结束行。

我目前正在使用StreamReader和ReadLine:

StreamReader srHexFile = File.OpenText(m_pathHexFile);
while ((readData = srHexFile.ReadLine()) != null)
....

但是我有最好的循环方式和设置/重置起始行和结束行的心理障碍。

提前感谢您的帮助!

根据来自@ user993533的建议,我正在使用以下函数,但它为firstZeroRow返回2881,它应该是2883.

这是新代码:

 private int FindEndofFlashData()
    {
        int lineNumber = 0;
        String readData;
        String zeroRowData = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
        int firstZeroRow = -1; // Will hold the location that starts the zero data
        //int lastZeroRow = m_numberOfFlashRows - 2;  // We know where to stop looking from m_numberOfFlashRows
        int lastZeroRow = -1;
        bool groupEnded = true;
        StreamReader srHexFile = File.OpenText(m_pathHexFile);

        /* Loop till the main flash row data ends, which will be used to calculate the number of lines in hex file for
         * flash rows.  Each line of hex file will have data for 1/2 th of a Flash row (64 bytes)*/
        while (((readData = srHexFile.ReadLine()) != null) && (lineNumber < (m_numberOfFlashRows*4 - 4)))
        {

            if ((readData[HEX_FILE_RECORD_TYPE_CHAR_0_INDEX] == HEX_FILE_DATA_RECORD_CHAR_0) && (readData[HEX_FILE_RECORD_TYPE_CHAR_1_INDEX] == HEX_FILE_DATA_RECORD_CHAR_1))
            {
                lineNumber++;

                if (readData.Substring(9, 128) == zeroRowData)
                {
                    if(groupEnded)
                    {
                        firstZeroRow = lineNumber;
                        groupEnded = false;
                    }

                    lastZeroRow = lineNumber;
                }
                else
                {
                    groupEnded = true;
                }
            }
            else
            {

                if ((readData[HEX_FILE_RECORD_TYPE_CHAR_0_INDEX] == HEX_FILE_EXTEND_LINEAR_RECORD_CHAR_0) &&
                    (readData[HEX_FILE_RECORD_TYPE_CHAR_1_INDEX] == HEX_FILE_EXTEND_LINEAR_RECORD_CHAR_1))
                {
                    if (readData[HEX_FILE_EXTENDED_ADDR_CHAR_1_INDEX] >= HEX_FILE_EXTENDED_ADDR_NON_FLASH_REGION)
                    {
                        break;
                    }
                }
            }

        }
        Console.WriteLine("First Zero Row is: {0}", firstZeroRow);
        Console.WriteLine("Last Zero Row is: {0}", lastZeroRow);
        return (firstZeroRow);
    }

2 个答案:

答案 0 :(得分:0)

    long firstZeroRow = -1;
    long lastZeroRow = -1;
    long rowNum = 0;

    StreamReader srHexFile = File.OpenText(m_pathHexFile);
    while ((readData = srHexFile.ReadLine()) != null){
       rowNum++;
       if (readData.equals(":0000000000" /*or ":0000000000\n"*/)){
           if (firstZeroRow == -1){
               firstZeroRow = rowNum;
           }
           lastZeroRow = rowNum;
       }
    }

    if (firstZeroRow == -1){
        System.out.println("firstZeroRow: " + firstZeroRow);
        System.out.println("lastZeroRow: " + lastZeroRow);
    }

答案 1 :(得分:0)

由于目前尚不清楚总体目标是什么......我采用了不同的方法。在读取数据时,我只是简单地列出了那些全为零的行,而不是试图在读取数据时处理最后的起始行和结束行。然后简单地将列表从高到低排序,以获得最后一行的行索引为零。然后使用相同的列表,从列表顶部开始,获取最后一个零(s)组的第一个/起始索引,检查相邻索引是否是连续的。如果索引是连续的,那么我们只是继续前进,直到下一个元素索引不连续,此时我们将知道最后一个组的起始位置。如果我们到达列表的末尾,那么你会知道列表以一行零开始,在这种情况下索引将为0.我知道我的索引从你的帖子中偏离1因为我开始时零(0)指数而非1。

private static void GetStartEndOfLastGroupOfZeros() {
  string readData = "";
  int rowNum = 0;
  List<int> rowsOfZero = new List<int>();
  StreamReader srHexFile = File.OpenText(m_pathHexFile);
  while ((readData = srHexFile.ReadLine()) != null) {
    if (readData.Equals(":0000000000")) {
      rowsOfZero.Add(rowNum);
    }
    rowNum++;
  }
  rowsOfZero.Reverse();
  PrintIndexes(rowsOfZero);
  if (rowsOfZero.Count < 1) {
    Console.WriteLine("There are NO rows that are :0000000000");
  }
  else {
    Console.WriteLine("\n\rStart line number of Last Zero Group: " + GetFirstIndexOfLastGroupOfZeroRows(rowsOfZero));
    Console.WriteLine("End line number of Last Zero Group: " + GetLastIndexOfLastGroupOfZeroRows(rowsOfZero));
  }
}

private static int GetFirstIndexOfLastGroupOfZeroRows(List<int> rowsOfZero) {
  if (rowsOfZero.Count < 1)  // <- if there are not any int in the list then there are no zero rows return -1;
    return -1;
  if (rowsOfZero.Count < 2)  // <- if there is only one row then it starts and ends on that single row
      return rowsOfZero[0];
  if (rowsOfZero[1] + 1 != rowsOfZero[0])  // <-- if the second element(1) is not contiguous, then the last row is a single zero row,
    return rowsOfZero[0];                  // <-- so the start line of the last group will be the same as the end line index 
  int startOfThisGroup = 0;
  for (int i = 2; i < rowsOfZero.Count; i++) {
    if (rowsOfZero[i] + 1 == rowsOfZero[i - 1]) {  // <-- if they are contiguous then we have a new startOfThisGroup row, if not we are done checking
      startOfThisGroup = rowsOfZero[i];
    }
    else {
      break;
    }
  }
  return startOfThisGroup;
}

private static int GetLastIndexOfLastGroupOfZeroRows(List<int> rowsOfZero) {
  if (rowsOfZero.Count < 1)
    return 0;
  return rowsOfZero[0];
}

private static void PrintIndexes(List<int> rowsOfZero) {
  if (rowsOfZero.Count < 1) {
    Console.WriteLine("No zero rows");
  }
  else {
    Console.Write("Sorted (high to low) row indexes that are ':0000000000' -> ");
    foreach (int curInt in rowsOfZero)
      Console.Write(curInt + " ");
  }
  Console.WriteLine("");
}

希望这有帮助。