Ejercicio: Lectura de archivos y escritura en ellos

Completado

También se puede usar la clase File de .NET para escribir datos en archivos y leer datos desde estos.

Ya casi ha terminado de crear una aplicación .NET maravillosa para Tailwind Traders. Hasta ahora, el código lee cualquier directorio, busca todos los archivos .json y crea un archivo totals.txt.

En este ejercicio, se completa el proyecto; para ello, se leen los archivos .json, se suman los totales de todas las tiendas y se escribe el total general en el archivo totals.txt.

Agregar System.Text.Json al proyecto

  1. Use el terminal para agregar Json.NET al proyecto.

    dotnet add package System.Text.Json
    

Preparación de los datos de ventas

  1. En la parte superior de Program.cs, agregue using Newtonsoft.Json:

    using System.Text.Json;
    
  2. En Program.cs, directamente debajo del método FindFiles, agregue un nuevo objeto record que modela los datos de sales.json:

    record SalesData (double Total);
    

Creación de un método para calcular totales de ventas

  1. En Program.cs, justo antes de la línea record que agregó en el paso anterior, cree una función que calcula el total de ventas. Este método debe tomar un IEnumerable<string> de rutas de acceso de archivo en el que pueda iterar.

    double CalculateSalesTotal(IEnumerable<string> salesFiles)
    {
        double salesTotal = 0;
    
        // READ FILES LOOP
    
        return salesTotal;
    }
    
  2. En este método, reemplace // READ FILES LOOP por un bucle que itere en salesFiles, lea el archivo, analice el contenido como JSON y, después, aumente la variable salesTotal con el valor total del archivo:

    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 = JsonSerializer.Deserialize<SalesData?>(salesJson);
    
            // Add the amount found in the Total field to the salesTotal variable
            salesTotal += data?.Total ?? 0;
        }
    
        return salesTotal;
    }
    

Llamada al método CalculateSalesTotals

  1. En el archivo Program.cs, agregue una llamada a la función CalculateSalesTotal justo encima de la llamada a 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);
    

Escritura del total en el archivo totals.txt

  1. En el archivo Program.cs, modifique el bloque File.WriteAllText para escribir el valor de la variable salesTotal en el archivo totals.txt. Durante el proceso, cambie la llamada File.WriteAllText a File.AppendAllText para que no se sobrescriba nada en el archivo.

    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. Pulse Ctrl+S / Cmd+S para guardar el archivo Program.cs.

Ejecución del programa

  1. Ejecute el programa desde el terminal:

    dotnet run
    

    No hay ninguna salida del programa. Si examina el archivo salesTotalDir/totals.txt, verá el total de todas las ventas del archivo sales.json.

  2. Vuelva a ejecutar el programa desde el terminal.

    dotnet run
    
  3. Seleccione el archivo salesTotalDir/totals.txt.

    El archivo totals.txt ahora tiene una segunda línea. Cada vez que el programa se ejecute, los totales se volverán a sumar y se escribirá una nueva línea en el archivo.

¡Gran trabajo! Hemos escrito una herramienta inteligente, eficaz y útil que Tailwind Traders puede usar para procesar todas las ventas de sus tiendas cada noche. En la siguiente unidad, revisaremos la información que hemos obtenido y algunas sugerencias que deberemos recordar.

¿Se ha bloqueado?

Si se ha bloqueado durante este ejercicio, aquí tiene el código completo de este proyecto:

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);