jueves, 12 de junio de 2014

El Demo del Día: Leer y Escribir Archivos de Texto usando Lista de Objetos

Leer y Escribir Archivos de Texto usando Lista de Objetos

Requerimiento
Se desea leer un archivo con registros separador por un carácter, por ejemplo por comas, punto y coma o por el símbolo "|".
Luego el usuario podrá modificar los registros existentes y al final debería grabar en el mismo archivo o si desea en otro archivo todo los registros.

Solución
La mejor solución es usar una Lista de Objetos debido a que esta consume menos memoria que el DataTable (exactamente la tercera parte) y se procesa mas rápido (la quinta parte aproximadamente), luego lo enlazamos a una grilla, en este caso el control DataGridView de WinForms y luego podemos grabar nuevamente el contenido de la Lista de Objetos en un archivo de texto.

Paso 1: Crear una Clase Genérica para crear los Métodos que usen la Lista de Objetos
using System.Reflection;
using System.IO;

namespace LeerCrearArchivoTextoLista
{
    public class ucTextoLista<T>
    {
    }
}

Paso 2: Función Genérica para Leer un Archivo de Texto en una Lista de Objetos
        public static List<T> TextoALista(string archivo, char separador)
        {
            List<T> lista = new List<T>();
            Type tipo = typeof(T);
            if (File.Exists(archivo))
            {
                using (StreamReader sr = new StreamReader(archivo))
                {
                    string[] cabeceras = sr.ReadLine().Split(separador);
                    if (cabeceras != null && cabeceras.Length > 0)
                    {
                        string[] campos = null;
                        object obe = null;
                        string tipoDato;
                        while (!sr.EndOfStream)
                        {
                            obe = Activator.CreateInstance(tipo);
                            campos = sr.ReadLine().Split(separador);
                            if (campos != null && campos.Length > 0)
                            {
                                for (int i = 0; i < campos.Length; i++)
                                {
                                    tipoDato =obe.GetType().GetProperty(cabeceras[i]).PropertyType.
                                                      ToString().ToLower();
                                    if (tipoDato.Contains("int16"))
                                    obe.GetType().GetProperty(cabeceras[i]).SetValue
                                      (obe, short.Parse(campos[i]));
                                    else
                                    {
                                        if (tipoDato.Contains("int32"))
                                        obe.GetType().GetProperty(cabeceras[i]).SetValue
                                          (obe, int.Parse(campos[i]));
                                        else
                                        {
                                            if (tipoDato.Contains("decimal"))
                                                obe.GetType().GetProperty(cabeceras[i]).SetValue
                                                  (obe, decimal.Parse(campos[i]));
                                            else obe.GetType().GetProperty(cabeceras[i]).
                                              SetValue(obe, campos[i]);
                                        }
                                    }
                                }
                            }
                            lista.Add((T)obe);
                        }
                    }
                }
            }
            return (lista);
        }

Paso 3: Función Genérica para Crear un Archivo de Texto desde una Lista de Objetos
        public static void ListaATexto(List<T> lista, string archivo, char separador)
        {
            using(FileStream fs = new FileStream(archivo, FileMode.Create, FileAccess.Write,
                    FileShare.Write))
            {
                using(StreamWriter sw = new StreamWriter(fs, Encoding.Default))
                {
                    PropertyInfo[] propiedades = lista[0].GetType().GetProperties();
                    for (int i = 0; i < propiedades.Length; i++)
                    {
                        sw.Write(propiedades[i].Name);
                        if (i < propiedades.Length - 1) sw.Write(separador);
                    }
                    sw.WriteLine();
                    for(int j = 0;j< lista.Count;j++)
                    {
                        propiedades = lista[j].GetType().GetProperties();
                        for (int i = 0; i < propiedades.Length; i++)
                        {
                            sw.Write(propiedades[i].GetValue(lista[j],null).ToString());
                            if (i < propiedades.Length - 1) sw.Write(separador);
                        }
                        sw.WriteLine();
                    }
                }
            }
        }

Paso 4: Archivo de Texto separados por un caractér (csv)
Crear un archivo de texto llamado "Productos.txt" con los siguientes datos:
ProductID,ProductName,SupplierID,CategoryID,UnitPrice,UnitsInStock
1,Chai,2,1,10.0000,76
2,Chang,7,4,3.0000,22
3,Chicha,10,1,10.0000,35
4,Chef Anton's Cajun Seasoning,2,2,22.0000,80
5,Chef Anton's Gumbo Mix,2,2,21.3500,31
6,Grandma's Boysenberry Spread,2,3,25.0000,50
7,Uncle Bob's Organic Dried Pears,3,7,30.0000,98
8,Northwoods Cranberry Sauce,3,2,40.0000,99
9,Mishi Kobe Niku,4,6,97.0000,96
10,Ikura,4,8,31.0000,93
..............................................................................

Paso 5: Crear una Clase Entidad para Almacenar los Productos
    public class beProducto
    {
        public int IdProducto { get; set; }
        public string Nombre { get; set; }
        public int IdProveedor { get; set; }
        public int IdCategoria { get; set; }
        public decimal PrecioUnitario { get; set; }
        public short Stock { get; set; }
    }

Paso 6: Crear un  Formulario con una Grilla que pueda usar las 2 Funciones
Asumiendo que las 2 funciones estáticas fueron creadas en una clase llamada "ucTextoLista" y hemos creado un formulario llamado: "frmPrueba" conteniendo un control DataGridView llamado: "dgvTexto" y 2 botones llamados: "btnLeerArchivoTxt" y "btnCrearArchivoTxt", tal como se muestra en la siguiente imagen:


Escribir el siguiente código en el formulario:
    public partial class frmPrueba : Form
    {
        List<beProducto> lista;

        public frmPrueba()
        {
            InitializeComponent();
        }

        private void btnLeerArchivoTxt_Click(object sender, EventArgs e)
        {
            lista = ucTextoLista<beProducto>.TextoALista("Productos.txt", ',');
            dgvTexto.DataSource = lista;
        }

        private void btnCrearArchivoTxt_Click(object sender, EventArgs e)
        {
            ucTextoLista<beProducto>.ListaATexto(lista,"Productos2.txt", ',');
            MessageBox.Show("Archivo de Texto creado");
        }
    }

Paso 7: Ejecutar la aplicación y Probar
Para ejecutar la aplicación se tiene que tener el archivo: "Productos.txt" en la carpeta bin/debug donde corre la aplicación con los datos descritos en el paso 4.
Primero dar clic al primer botón: "Leer Archivo Txt" y se cargarán los datos de los productos desde el archivo; luego ingresar nuevos registros, modificar los existentes y finalmente dar clic al botón "Crear Archivo Txt" y observar que se ha creado en la carpeta bin/debug el archivo "Productos2.txt".


Comentario:
Esta forma de leer y crear archivos de texto es mas rápida pero necesita conocer Reflection para trabajar con una Lista de Objetos y poder deducir sus propiedades, recuperar valores y asignar valores a cualquier tipo de objeto. Como pocos desarrolladores conocen el poder de Reflection se van por el "lado oscuro" (ineficiente pero fácil) y terminan trabajando con el DataSet, DataTable, DataView, XML, etc.

Descarga:
Demo02_LeerCrearArchivoTextoLista

Libro La Biblia de Visual Basic .NET - Preguntas de Repaso - Capítulo 1

Preguntas de Repaso: .NET Framework

1.    Qué es .NET Framework?

2.    Menciona 3 tipos de aplicaciones que se pueden crear en .NET Framework.

3.    Que tecnologías aparecieron con .NET Framework 3?

4.    Menciona 5 lenguajes .NET.

5.    Cuál es el criterio principal para seleccionar un Lenguaje .NET?

6.    Que lenguaje es recomendable para aquellos que no tienen experiencia con C, Java o la POO.

7.    Cuáles son los componentes principales de .NET Framework?

8.    Que es la BCL del .NET Framework?

9.    Cómo se clasifican los tipos en .NET Framework?

10. Menciona 3 tipos complejos por referencia.

11. Cuál es la principal función de un espacio de nombres (Namespace)?

12. Menciona 5 espacios de nombres de la BCL.

13. Qué es el CLR del .NET Framework?

14. Cómo se llama el programa del CLR que se encarga de liberar automáticamente la memoria que no esta siendo utilizada?

15. En qué tipo de lenguaje escriben el código los desarrolladores .NET

16. Qué es un ensamblado (Assembly) y en que lenguaje se encuentra?

17. Qué tipo de código ejecuta el CLR y en que lenguaje se encuentra?

18. Menciona 3 funciones del CLR.

19. Cuáles son los nuevos métodos de la clase Environment para verificar sistemas y procesos de 64 bits?

20. Cuáles son los nuevos métodos de la clase Directory para listar directorios y archivos?

21. Con qué clase se puede manejar los archivos asignados a memoria?

22. Qué métodos se han agregado para la clase String y StringBuilder respectivamente para facilitar el manejo de cadenas?

23. Cuál es el espacio de nombres para trabajar con programación paralela?

24. Menciona 3 mejoras en ASP .NET.

25. Cuáles son los nuevos controles que han aparecido en WPF?

26. Cuál es la ventaja principal de usar el Visual Studio 2010 en el desarrollo de una Aplicación?

27. Menciona 3 ventanas del IDE de Visual Studio 2010.

28. Menciona 3 novedades del Editor de Visual Studio 2010.

29. Con qué otros productos Microsoft se integra el desarrollo desde Visual Studio 2010?

30. Cuáles son las estructuras de decisión de Visual Basic .NET?

31. Cuáles son las estructuras de bucles de Visual Basic .NET?

32. Qué estructura adicional de Visual Basic simplifica la sintaxis y el acceso a un objeto?

33. Menciona 5 tipos de datos simples en Visual Basic.

34. Menciona 5 operadores aritméticos de Visual Basic?

35. Qué operador es más rápido para sumar 2 cadenas: “+” o “&”.

36. Cuáles son los operadores lógicos de corto circuito en Visual Basic?

37. Qué tipo de variable debe usarse en lo posible en Visual Basic?

38. Menciona 3 novedades de Visual Basic 2010.

El Libro del Día: Beginning ASP.NET MVC 4

El Libro del Día: 2014-06-12

Titulo: Beginning ASP.NET MVC 4
Autor: José Rolando Guay Paz
Editorial: Apress
Nro Paginas: 292

Capítulos:
Chapter 1: Introducing ASP.NET MVC 4
Chapter 2: Installing ASP.NET MVC 4
Chapter 3: The “Have You Seen Me?” ASP.NET MVC 4 Web Application
Chapter 4: Controllers
Chapter 5: Views
Chapter 6: Models
Chapter 7: Data Validation
Chapter 8: Ajax and jQuery
Chapter 9: Security
Chapter 10: Routing
Chapter 11: Testing the Application
Chapter 12: Deploying the Application

Descarga:
Beginning_ASP.NET_MVC4

miércoles, 11 de junio de 2014

El Demo del Día: Leer y Escribir Archivos de Texto usando DataTable

Leer y Escribir Archivos de Texto usando DataTable

Requerimiento
Se desea leer un archivo con registros separador por un carácter, por ejemplo por comas, punto y coma o por el símbolo "|".
Luego el usuario podrá modificar los registros existentes y al final debería grabar en el mismo archivo o si desea en otro archivo todo los registros.

Solución
Una alternativa sería leer el archivo y almacenarlo en un DataTable de ADO .NET (aunque no es lo mejor), luego lo enlazamos a una grilla, en este caso el control DataGridView de WinForms y luego podemos grabar nuevamente el contenido del DataTable a un archivo de texto.

Paso 1: Función Genérica para Leer un Archivo de Texto en un DataTable
        public static DataTable TextoATabla(string archivo, char separador)
        {
            DataTable tabla = new DataTable();
            if (File.Exists(archivo))
            {
                using (StreamReader sr = new StreamReader(archivo))
                {
                    string[] cabeceras = sr.ReadLine().Split(separador);
                    if (cabeceras != null && cabeceras.Length > 0)
                    {
                        for (int i = 0; i < cabeceras.Length; i++)
                        {
                            tabla.Columns.Add(cabeceras[i], Type.GetType("System.String"));
                        }
                        DataRow fila = null;
                        string[] campos = null;
                        while (!sr.EndOfStream)
                        {
                            fila = tabla.NewRow();
                            campos = sr.ReadLine().Split(separador);
                            if (campos != null && campos.Length > 0)
                            {
                                for (int i = 0; i < campos.Length; i++)
                                {
                                    fila[i] = campos[i];
                                }                              
                            }
                            tabla.Rows.Add(fila);
                        }
                    }
                }
            }
            return (tabla);
        }

Paso 2: Función Genérica para Crear un Archivo de Texto desde un DataTable
        public static void TablaATexto(DataTable tabla, string archivo,char separador)
        {
            using(FileStream fs = new FileStream(archivo, FileMode.Create, FileAccess.Write, 
                    FileShare.Write))
            {
                using(StreamWriter sw = new StreamWriter(fs, Encoding.Default))
                {
                    for(int i = 0;i< tabla.Columns.Count;i++)
                    {
                        sw.Write(tabla.Columns[i].ColumnName);
                        if(i<tabla.Columns.Count - 1) sw.Write(separador);
                    }
                    sw.WriteLine();
                    for(int j = 0;j< tabla.Rows.Count;j++)
                    {
                        for(int i = 0;i< tabla.Columns.Count;i++)
                        {
                            sw.Write(tabla.Rows[j][i].ToString());
                            if(i<tabla.Columns.Count - 1) sw.Write(separador);
                        }
                        sw.WriteLine();
                    }
                }
            }
        }
Nota: Ambas funciones usan el Namespace System.IO y System.Data

Paso 3: Archivo de Texto separados por un caractér (csv)
ProductID,ProductName,SupplierID,CategoryID,UnitPrice,UnitsInStock
1,Chai,2,1,10.0000,76
2,Chang,7,4,3.0000,22
3,Chicha,10,1,10.0000,35
4,Chef Anton's Cajun Seasoning,2,2,22.0000,80
5,Chef Anton's Gumbo Mix,2,2,21.3500,31
6,Grandma's Boysenberry Spread,2,3,25.0000,50
7,Uncle Bob's Organic Dried Pears,3,7,30.0000,98
8,Northwoods Cranberry Sauce,3,2,40.0000,99
9,Mishi Kobe Niku,4,6,97.0000,96
10,Ikura,4,8,31.0000,93
..............................................................................

Paso 4: Crear un  Formulario con una Grilla que pueda usar las 2 Funciones
Asumiendo que las 2 funciones estáticas fueron creadas en una clase llamada "ucTextoTabla" y hemos creado un formulario llamado: "frmPrueba" conteniendo un control DataGridView llamado: "dgvTexto" y 2 botones llamados: "btnLeerArchivoTxt" y "btnCrearArchivoTxt", tal como se muestra en la siguiente imagen:


Escribir el siguiente código en el formulario:
    public partial class frmPrueba : Form
    {
        DataTable tabla;

        public frmPrueba()
        {
            InitializeComponent();
        }

        private void btnLeerArchivoTxt_Click(object sender, EventArgs e)
        {
            tabla = ucTextoTabla.TextoATabla("Productos.txt", ',');
            dgvTexto.DataSource = tabla;
        }

        private void btnCrearArchivoTxt_Click(object sender, EventArgs e)
        {
            ucTextoTabla.TablaATexto(tabla,"Productos2.txt", ',');
            MessageBox.Show("Archivo de Texto creado");
        }
    }

Paso 5: Ejecutar la aplicación y Probar
Para ejecutar la aplicación se tiene que tener el archivo: "Productos.txt" en la carpeta bin/debug donde corre la aplicación con los datos descritos en el paso 3.
Primero dar clic al primer botón: "Leer Archivo Txt" y se cargarán los datos de los productos desde el archivo; luego ingresar nuevos registros, modificar los existentes y finalmente dar clic al botón "Crear Archivo Txt" y observar que se ha creado en la carpeta bin/debug el archivo "Productos2.txt".


Espero les guste el primer Demo y este fue un pedido. Ya saben que cualquier solicitud o requerimiento es bienvenida. No se olviden sus comentarios.

Descarga:
Demo01_LeerCrearArchivoTexto



El Libro del Día: .NET Domain-Driven Design with C#

El Libro del Día: 2014-06-11

Titulo: .NET Domain-Driven Design with C#
Autor: Tim McCarthy
Editorial: Wrox
Nro Paginas: 435

Capítulos:
Chapter 1: Introducing the Project: The SmartCA Application
Chapter 2: Designing the Layered Architecture
Chapter 3: Managing Projects
Chapter 4: Companies and Contacts
Chapter 5: Submittal Transmittals
Chapter 6: Requests for Information
Chapter 7: Proposal Requests
Chapter 8: Change Orders
Chapter 9: Construction Change Directives
Chapter 10: Synchronizing With the Server
Chapter 11: The Client Membership System

Descarga:
NET_DomainDrivenDesign_C#

martes, 10 de junio de 2014

El Libro del Día: Ultra-Fast ASP.NET 4.5

El Libro del Día: 2014-06-10

Titulo: Ultra-Fast ASP.NET 4.5
Autor: Richard Kiessig
Editorial: Apress
Nro Paginas: 459

Capítulos:
Chapter 1: Principles and Method
Chapter 2: Client Performance
Chapter 3: Caching
Chapter 4: IIS 7.5
Chapter 5: ASP.NET Threads and Sessions
Chapter 6: Using ASP.NET to Implement and Manage Optimization Techniques
Chapter 7: Managing ASP.NET Application Policies
Chapter 8: SQL Server Relational Database
Chapter 9: SQL Server Analysis Services
Chapter 10: Infrastructure and Operations
Chapter 11: Putting It All Together

Descarga:
UltraFast_ASP.NET_4.5

lunes, 9 de junio de 2014

El Libro del Día: Pro HTML5 Programming

El Libro del Día: 2014-06-09

Titulo: Pro HTML5 Programming
Autor: Peter Lubbers, Brian Albers, Frank Salim
Editorial: Apress
Nro Paginas: 305

Capítulos:
Chapter 1: Overview of HTML5
Chapter 2: Using the HTML5 Canvas API
Chapter 3: Working with HTML5 Audio and Video
Chapter 4: Using the HTML5 Geolocation API
Chapter 5: Using the Communication APIs
Chapter 6: Using the HTML5 WebSocket API
Chapter 7: Using the HTML5 Forms API
Chapter 8: Using the HTML5 Web Workers API
Chapter 9: Using the HTML5 Web Storage API
Chapter 10: Creating HTML5 Offline Web Applications
Chapter 11: The Future of HTML5

Descarga:
ProHTML5_Programming