C# - 读取文件的特定部分并将每一行拆分为数组或列表

C# - Reading specific part of a File and splitting each line into an array or a list

首先,大家好。我是 C# 的初学者,正在尝试做这个作业。我的问题是,读取 .pdb(蛋白质数据库)文件的特定部分并将该特定行拆分为数组或列表。然后我会用它做一个 Forms App

所以 .pdb 文件索引看起来像这样;

HEADER    ANTIFREEZE 17-SEP-97   7MSI              
TITLE     TYPE III ANTIFREEZE PROTEIN ISOFORM HPLC 12                           
COMPND    MOL_ID: 1;                                                            
COMPND   2 MOLECULE: TYPE III ANTIFREEZE PROTEIN ISOFORM HPLC 12;       
SOURCE    MOL_ID: 1;                                                            
SOURCE   2 ORGANISM_SCIENTIFIC: MACROZOARCES AMERICANUS;

ATOM      1  N   MET A   0      18.112  24.345  32.146  1.00 51.10           N  
ATOM      2  CA  MET A   0      18.302  23.436  31.020  1.00 49.06           C  
ATOM      3  C   MET A   0      18.079  24.312  29.799  1.00 46.75           C  
ATOM      4  O   MET A   0      16.928  24.678  29.560  1.00 48.24           O  
ATOM      5  CB  MET A   0      17.257  22.311  31.008  1.00 48.14           C  
ATOM      6  N   ALA A   1      19.106  24.757  29.076  1.00 43.47           N

HETATM  491  O   HOH A 101      23.505  19.335  23.451  1.00 35.56           O  
HETATM  492  O   HOH A 102      19.193  19.013  25.418  1.00 12.73           O  
HETATM  493  O   HOH A 103       7.781  12.538  12.927  1.00 80.11           O

..... 然后继续这样

我只需要阅读以"ATOM"关键字开头的行。然后我想将他们的信息拆分为变量和数组或列表。之后我想将 X 坐标的最大值打印到标签上。

例如;

ATOM     1  N   MET A   0      18.112  24.345  32.146  1.00 51.10           N

1代表原子序数

N代表原子名

MET代表氨基酸名称

18.112代表X坐标等

我做了什么

我使用了之前在此处提出的类似问题的代码,但无法将其应用到我的项目中。 首先,我为变量

创建了一个 Class
class Atom
{
    public int atom_no;
    public string atom_name;
    public string amino_name;
    public char chain;
    public int amino_no;
    public float x_coordinate;
    public float y_coordinate;
    public float z_coordinate;
    public float ratio;
    public float temperature;
}

为主体class;注意:我应该提到变量之间没有单个空格。例如在 "MET" 和 "A" 之间有额外的 3 或 4 个空格。我试图在读取文件时删除它们,但我不知道是否有效..

     private void button1_Click(object sender, EventArgs e)
        {
            string filePath = @"path_of_file";
            string stringToSearch = @"ATOM";


      List<Atom> Atoms = new List<Atom>();
      using (StreamReader sr = new StreamReader(filePath))
          {
          string[] lines = File.ReadAllLines(filePath);

             foreach (string line in lines)
             {
             if (line.Contains(stringToSearch))   // i have tried to read the parts that starts with ATOM
             {
               while (sr.Peek() >= 0)   //this while part is from the question asked before
               {
                   string[] strArray;
                   string line1 = sr.ReadLine();               // i've added theese 2 lines to remove the extra whitespaces 
                   var lineParts = line1.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

                    strArray = line1.Split(' ');
                    Atom currentAtom = new Atom();
                    currentAtom.atom_no = int.Parse(strArray[0]);
                    currentAtom.atom_name = strArray[1];
                    currentAtom.amino_name = strArray[2];
                    currentAtom.chain = char.Parse(strArray[3]);
                    currentAtom.amino_no = int.Parse(strArray[4]);
                    currentAtom.x_coordinate = float.Parse(strArray[5]);
                    currentAtom.y_coordinate = float.Parse(strArray[6]);
                    currentAtom.z_coordinate = float.Parse(strArray[7]);
                    currentAtom.ratio = float.Parse(strArray[8]);
                    currentAtom.temperature = float.Parse(strArray[9]);

                    Atoms.Add(currentAtom);

                }

             }
         }


      }
      listBox1.DataSource = Atoms;
      listBox1.ValueMember = "atom_no";
      listBox1.DisplayMember = "atom_name";

}

我还没有将要打印 X 坐标最大值的部分添加到标签中。我此时正在使用列表框进行测试。所以当我 运行 代码并按下按钮时,在 currentAtom.atom_no = int.Parse(strArray[0]); 行给我 "Input string was not in a correct format" 错误。

我知道我的代码看起来很乱,很抱歉,如果我在这上面耽误了您的时间。如果你们能帮我做这个 Forms 应用程序作为我的家庭作业,我将不胜感激。如果没有,仍然感谢您阅读它。祝你有美好健康的一天..

一种方法是只使用 File.ReadAllLines 读取文件,然后过滤掉任何不 StartWith stringToSearch 文本的行(使用 System.Linq 方法 Where),最后 select 使用 Split 方法(并删除空条目)从每一行开始新的 Atom,最后返回他们都是 ToList:

List<Atom> Atoms = File.ReadAllLines(filePath)       // Read all the lines
    .Where(line => line.StartsWith(stringToSearch))  // Filter on our string
    .Select(line =>
    {
        // Split the line on the space character into an array 
        var strArray = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);

        // Return a new Atom for each line based on the array contents
        return strArray.Length < 10  // Ensure we have at least ten elements in the array
            ? null                   // If we don't have 10, return 'null'
            : new Atom               // Otherwise return a new atom from the array
            {
                atom_no = int.Parse(strArray[0]),
                atom_name = strArray[1],
                amino_name = strArray[2],
                chain = char.Parse(strArray[3]),
                amino_no = int.Parse(strArray[4]),
                x_coordinate = float.Parse(strArray[5]),
                y_coordinate = float.Parse(strArray[6]),
                z_coordinate = float.Parse(strArray[7]),
                ratio = float.Parse(strArray[8]),
                temperature = float.Parse(strArray[9])
            };
    })
    .ToList();                       // Return the items as a list