练习 - 读取和写入文件

已完成

还可以使用 .NET 中的 File 类将数据写入文件以及从文件中读取数据。

你基本已完成为 Tailwind Traders 创建极佳 .NET 工具的操作。 到目前为止,你的代码能够读取所有目录,查找所有 .json 文件,并创建一个“totals.txt”文件。

在本练习中,你将读取 .json 文件,加总商店销售额,并将总额写入“totals.txt”文件,从而完成项目。

将 Json.NET 添加到项目

  1. 使用终端将 Json.NET 添加到项目。

    dotnet add package Newtonsoft.Json
    

准备销售数据

  1. Program.cs 顶部添加 using Newtonsoft.Json

    using Newtonsoft.Json;
    
  2. FindFiles 方法下的 Program.cs 中,添加一个新的 record,用于对 sales.json 数据建模:

    record SalesData (double Total);
    

创建用于计算销售总额的方法

  1. Program.cs 中,就在在上一步中添加的 record 行之前,创建一个新函数,用于计算销售总额。 此方法应采用它可以循环访问的文件路径的 IEnumerable<string>

    double CalculateSalesTotal(IEnumerable<string> salesFiles)
    {
        double salesTotal = 0;
    
        // READ FILES LOOP
    
        return salesTotal;
    }
    
  2. 在该方法中,将 // READ FILES LOOP 替换为循环访问 salesFiles 的循环、读取文件、将内容分析为 JSON,然后使用文件中的 total 值递增 salesTotal 变量:

    double CalculateSalesTotal(IEnumerable<string> salesFiles)
    {
        double salesTotal = 0;
    
        // Loop over each file path in salesFiles
        foreach (var file in salesFiles)
        {      
            // Read the contents of the file
            string salesJson = File.ReadAllText(file);
    
            // Parse the contents as JSON
            SalesData? data = JsonConvert.DeserializeObject<SalesData?>(salesJson);
    
            // Add the amount found in the Total field to the salesTotal variable
            salesTotal += data?.Total ?? 0;
        }
    
        return salesTotal;
    }
    

调用 CalculateSalesTotals 方法

  1. Program.cs 文件中,添加对 CalculateSalesTotal 函数的调用,就在 File.WriteAllText 调用的上方:

    var currentDirectory = Directory.GetCurrentDirectory();
    var storesDir = Path.Combine(currentDirectory, "stores");
    
    var salesTotalDir = Path.Combine(currentDirectory, "salesTotalDir");
    Directory.CreateDirectory(salesTotalDir);
    
    var salesFiles = FindFiles(storesDir);
    
    var salesTotal = CalculateSalesTotal(salesFiles); // Add this line of code
    
    File.WriteAllText(Path.Combine(salesTotalDir, "totals.txt"), String.Empty);
    

将总额写入 totals.txt 文件

  1. Program.cs 文件中,修改块 File.WriteAllText,将 salesTotal 变量的值写入“totals.txt”文件。 同时,将 File.WriteAllText 调用更改为 File.AppendAllText,这样可确保文件中的内容不会被覆盖。

    var currentDirectory = Directory.GetCurrentDirectory();            
    var storesDir = Path.Combine(currentDirectory, "stores");
    
    var salesTotalDir = Path.Combine(currentDirectory, "salesTotalDir");
    Directory.CreateDirectory(salesTotalDir);            
    
    var salesFiles = FindFiles(storesDir);
    
    var salesTotal = CalculateSalesTotal(salesFiles);
    
    File.AppendAllText(Path.Combine(salesTotalDir, "totals.txt"), $"{salesTotal}{Environment.NewLine}");
    
  2. Ctrl+S / Cmd+S 保存 Program.cs 文件。

运行程序

  1. 从终端运行程序:

    dotnet run
    

    程序无输出。 如果查看 salesTotalDir/totals.txt 文件,会看到 sales.json 文件中所有销售的总额。

  2. 再次从终端运行程序。

    dotnet run
    
  3. 选择“salesTotalDir/totals.txt”文件。

    “totals.txt”文件现在有了第二行。 每次运行该程序时,都会再次加总总额,并在文件中写入新行。

非常棒! 你现在已编写了一个智能、可靠且方便的工具,Tailwind Traders 每晚都可以使用它来处理其所有商店销售额。 在下一单元中,我们将回顾你已学习的内容,并说明要记住的几个提示。

遇到困难了?

如果在此练习中遇到问题,可参考以下此项目的完整代码:

using Newtonsoft.Json; 

var currentDirectory = Directory.GetCurrentDirectory();
var storesDirectory = Path.Combine(currentDirectory, "stores");

var salesTotalDir = Path.Combine(currentDirectory, "salesTotalDir");
Directory.CreateDirectory(salesTotalDir);   

var salesFiles = FindFiles(storesDirectory);

var salesTotal = CalculateSalesTotal(salesFiles);

File.AppendAllText(Path.Combine(salesTotalDir, "totals.txt"), $"{salesTotal}{Environment.NewLine}");

IEnumerable<string> FindFiles(string folderName)
{
    List<string> salesFiles = new List<string>();

    var foundFiles = Directory.EnumerateFiles(folderName, "*", SearchOption.AllDirectories);

    foreach (var file in foundFiles)
    {
        var extension = Path.GetExtension(file);
        if (extension == ".json")
        {
            salesFiles.Add(file);
        }
    }

    return salesFiles;
}

double CalculateSalesTotal(IEnumerable<string> salesFiles)
{
    double salesTotal = 0;
    
    // Loop over each file path in salesFiles
    foreach (var file in salesFiles)
    {      
        // Read the contents of the file
        string salesJson = File.ReadAllText(file);
    
        // Parse the contents as JSON
        SalesData? data = JsonConvert.DeserializeObject<SalesData?>(salesJson);
    
        // Add the amount found in the Total field to the salesTotal variable
        salesTotal += data?.Total ?? 0;
    }
    
    return salesTotal;
}

record SalesData (double Total);