sábado, 25 de julio de 2015

Receta C# No. 5-25: Procesamiento de un Archivo de Registro (Log)

Índice

0. Introducción
1. Problema
2. Solución
3. Discusión de la Solución
3.1 Método static File.ReadLines
3.2 Filtros con LINQ
4. Práctica: Código C#
5. Conclusiones
6. Glosario
7. Literatura & Enlaces

0. Introducción

En la receta C# anterior (5-24) aprendimos a escribir información de eventos (e.g., errores, excepciones) en un archivo de registros de eventos; la oportunidad de ahora consiste en procesar estos archivos con el uso del método static File.ReadLines y el uso de expresiones LINQ para obtener líneas específicas en el archivo.

1. Problema

Contamos con una serie de archivos de registros de eventos y queremos procesar su contenido.

2. Solución

En C# contamos con el método File.ReadLines [2] para leer el contenido de todas las líneas de un archivo de texto. Podemos procesar esas líneas de texto con consultas o filtros LINQ.

3. Discusión de la Solución

3.1 Método static File.ReadLines

El método sobrecargado static File.ReadLines [2] lee cada una de las líneas de un archivo. En la Figura 1 de muestran las versiones sobrecargadas de este método. 
Versiones sobrecargadas de File.ReadLines
Figura 1. Versiones sobrecargadas de File.ReadLines [2].

Vale mencionar, que a diferencia del método File.ReadAllLines [3], File.ReadLines permite trabajar de forma más eficiente con archivos grandes gracias a que la enumeración de la colección de cadenas se ejecuta primero antes de retornar la colección de objetos string [2]; esto no ocurre con File.ReadAllLines, dado que se debe esperar hasta que la colección de objetos string se retorna para hacer cualquier enumeración y/o aplicación de un filtro.


File.ReadLines usa el sistema de codificación UTF-8 para las cadenas de caracteres [2]. Por otra parte, podemos usar LINQ para filtrar las líneas contenidas en un archivo leído por File.ReadLines.

3.2 Filtros con LINQ

No nos extenderemos en esta sección de creación de filtros con el lenguaje de consulta integrado -LINQ-. Incluyo el siguiente enlace para conocer los detalles de la receta que explica el proceso de selección de elementos específicos de una colección -Receta No. 2-17 en C#: Selección de Elementos de un Arreglo o Colección-, además, del siguiente código de ejemplo extraído desde esa misma receta: 

En las líneas 9-28 declaramos la clase Fruta con un constructor, y dos propiedades (i.e., Nombre, y Color). La clase de prueba, FrutaLinq (líneas 30-73) tiene declarado el punto de entrada a la aplicación, Main
  • Línea 35: Creación de una instancia concreta de List con objetos Fruta.
  • Línea 49: Usamos la versión estándar de LINQ para seleccionar aquellas frutas con color distinto a rojo y que su nombre no empiece por el carácter 'p'.
  • Línea 61: Aquí utilizamos métodos de extensión (Métodos de Extensión en C#) de LINQ (i.e., Where, OrderBy, Select) con expresiones lambda para hacer la misma consulta anterior.
Compilación: 

  1. csc /target:exe FrutaLinq.cs

Ejecución assembly

  1. .\FrutaLinq.exe

> Prueba de ejecución: http://ideone.com/b2OgMj

> Prueba de ejecución: 
Ejecución assembly FrutaLinq.exe
Figura 2. Ejecución assembly FrutaLinq.exe.

4. Práctica: Código C#

En esta receta reutilizaremos el archivo log_completo.log ([enlace alternativo][enlace alternativo]) creado en la receta anterior para obtener aquellas entradas (líneas) que sólo incluyan al principio la palabra Error. Lo anterior usando LINQ.

Con la expresión 

IEnumerable<string> registros = File.ReadAllLines("log_completo.log");


(línea 18) leemos todas las líneas del archivo de registros de eventos. Notemos que aquí hemos definido a registros como un tipo IEnumerable para objetos string. Con el ciclo foreach (líneas 19-22) mostramos cada una de las líneas en la colección referenciada por registros.

Con 

IEnumerable<string> registrosError = File.ReadLines("log_completo.log").Where(e => e.StartsWith("Error"));

(línea 25) usamos LINQ y su método de extensión Where para crear la consulta que selecciona aquellos líneas del log que empiezan con los caracteres Error.


Compilación: 


  1. csc /target:exe SeleccionRegistros.cs


Ejecución assembly


  1. .\SeleccionRegistros.exe

> Prueba de ejecución: 
Ejecución assembly SeleccionRegistros.exe
Figura 3. Ejecución assembly SeleccionRegistros.exe.

5. Conclusiones

Hemos visto cómo es de sencillo seleccionar todos o algunos registros de un archivo de log utilizando LINQ (en especial para el segundo caso). Conocer LINQ ya se convierte en una necesidad explícita y urgente (seguramente en la proximidad ya empezaremos a redactar recetas LINQ).


La siguiente receta C# es la última de la serie de Archivos, Directorios, y Entrada y Salida: aprenderemos a enviar y recibir datos entre distintos procesos.

6. Glosario

  • Archivo
  • Consulta
  • Directorio
  • Filtro
  • LINQ
  • Proceso
  • Selección

7. Literatura & Enlaces

[1]: Visual C# 2010 Recipes by Allen Jones and Adam Freeman. Copyright 2010 Allen Jones and Adam Freeman, 978-1-4302-2525-6.
[2]: File.ReadLines Method (System.IO) - https://msdn.microsoft.com/en-us/library/system.io.file.readlines(v=vs.110).aspx
[3]: File.ReadAllLines Method (System.IO) - https://msdn.microsoft.com/en-us/library/system.io.file.readalllines(v=vs.110).aspx
[4]: Receta No. 2-17 en C#: Selección de Elementos de un Arreglo o Colección - http://ortizol.blogspot.com/2014/05/receta-no-2-17-en-c-seleccion-de.html
[5]: Métodos de Extensión en C# - http://ortizol.blogspot.com/2014/09/metodos-de-extension-en-csharp.html


V

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.