从文件读取数据和存储的最佳方式?

Best way to read data and store from file?

我有一个以这种方式存储数据的文本文件:

Player name: NAME HERE
Speed: 7
Strength: 9
Stamina: 4
Player name: ANOTHER NAME HERE
Speed: 5
Strength: 8
Stamina: 3

同一个文件包含大约 15 个不同的选手,我想从他们每个人那里收集数值,存储在一个临时的比赛变量中,然后计算速度强度和耐力的平均值并给出获胜者。我的第一个想法是使用正则表达式,但我目前正在研究是否有另一种更可持续的方法来做到这一点。

这是我的一个副项目,欢迎任何帮助。谢谢

如果文件格式是固定的,解决这个问题的一种方法是使用 System.IO.File.ReadAllLines 获取文件中的每一行,然后遍历行,拆分密钥([=12 的左侧) =]) 和值(: 右边)。使用处理每一行时从文件中读取的值填充某种数据对象(下例中的PlayerObject)。

PlayerObject player = new PlayerObject();
string[] allLines = System.IO.File.ReadAllLines(FILE_PATH_HERE);
foreach(string dataPair in allLines)
{
    string[] pair = dataPair.Split(new[] { ':' });
    if(pair.Length == 2)
    {
        switch(pair[0])
        {
            case "Player name": /*process pair[1]*/ break;
            case "Speed": /*process pair[1]*/ break;
            //other possible key strings here
            //recommend defining these as constants
        }
    }
}

这将允许您对文件中的参数重新排序(或至少支持不同的排序),如果缺少任何参数,可以将它们预先设置为数据对象中的某个默认值。

您的格式中唯一缺少的是记录之间的某种标记值。现在您可以假设每个玩家都由一个新的 "Player name" 条目描述,并在您阅读下一个 "Player name".

后开始填充下一个 PlayerObject

定义你的种族Class结构:

public class Race
{
    public string Name;
    public int Speed;
    public int Strength;
    public int Stamina;
}

从文本文件中读取数据,实例化 Race 对象并将它们收集到 List<Race> 中。收集完成后,您可以通过 List 调用 Average() 获取结果。

string[] myTextFileLines = File.ReadAllLines(myTextFile);

List<Race> myRaces = new List<Race>();
for (int i = 0; i < myTextFileLines.Length; i += 4)
{
    myRaces.Add(new Race()
                    {
                        Name = myTextFileLines[i].Substring(myTextFileLines[i].IndexOf(":") + 2),
                        Speed = Convert.ToInt32(myTextFileLines[i + 1].Substring(myTextFileLines[i + 1].IndexOf(":") + 2)),
                        Strength = Convert.ToInt32(myTextFileLines[i + 2].Substring(myTextFileLines[i + 2].IndexOf(":") + 2)),
                        Stamina = Convert.ToInt32(myTextFileLines[i + 3].Substring(myTextFileLines[i + 3].IndexOf(":") + 2)),
                    });
}

Console.WriteLine("Avg Speed: {0}", myRaces.Average(r => Convert.ToDouble(r.Speed)));
Console.WriteLine("Avg Strength: {0}", myRaces.Average(r => Convert.ToDouble(r.Strength)));
Console.WriteLine("Avg Stamina: {0}", myRaces.Average(r => Convert.ToDouble(r.Strength)));
Console.ReadLine();

结果(使用您在问题中提供的确切数据):

XML 解决方案示例:

Players.xml

<?xml version="1.0" encoding="utf-8" ?>
<players>
  <player name="Alice">
    <speed>7</speed>
    <strength>9</strength>
    <stamina>4</stamina>
  </player>
  <player name="Bob">
    <speed>5</speed>
    <strength>8</strength>
    <stamina>3</stamina>
  </player>
</players>

C# 代码

    private class Player
    {
        public string Name { get; set; }
        public int Speed { get; set; }
        public int Strength { get; set; }
        public int Stamina { get; set; }

        public override string ToString()
        {
            return "Name: " + Name + Environment.NewLine +
                   "Speed: " + Speed + Environment.NewLine +
                   "Strength: " + Strength + Environment.NewLine +
                   "Stamina: " + Stamina + Environment.NewLine;
        }
    }

    private static void PrintXmlPlayers(XmlNode players)
    {
        foreach (XmlNode player in players.SelectNodes("player"))
        {
            string playerName = player.Attributes["name"].InnerText;
            int playerSpeed = XmlConvert.ToInt32(player["speed"].InnerText);
            int playerStrength = XmlConvert.ToInt32(player["strength"].InnerText);
            int playerStamina = XmlConvert.ToInt32(player["stamina"].InnerText);

            Player aPlayer = new Player
            {
                Name = playerName,
                Speed = playerSpeed,
                Strength = playerStrength,
                Stamina = playerStamina
            };

            Console.WriteLine(aPlayer);
        }
    }

    private static void TestXml()
    {
        // path of document is relative to executable
        const string xmlPath = "../../Players.xml";

        XmlDocument doc = new XmlDocument();
        doc.Load(xmlPath);

        XmlNode players = doc["players"];
        PrintXmlPlayers(players);

        XmlNode alice = players.SelectSingleNode("player[@name='Alice']");
        string aliceOldString = alice["strength"].InnerText;
        alice["strength"].InnerText = "10";
        doc.Save(xmlPath);

        PrintXmlPlayers(players);

        alice["strength"].InnerText = aliceOldString;
        doc.Save(xmlPath);
    }

输出

Name: Alice
Speed: 7
Strength: 9
Stamina: 4

Name: Bob
Speed: 5
Strength: 8
Stamina: 3

Name: Alice
Speed: 7
Strength: 10
Stamina: 4

Name: Bob
Speed: 5
Strength: 8
Stamina: 3