10 de febrero de 2012

StreamReader y StreamWriter 1/2


Como siempre, mas de alguna vez se necesitara leer la informacion desde o crear un archivo de texto en las aplicaciones, sea cual sea el lenguaje de programacion, para el caso de Visual Studio(VB o C#) StreamReader y StreamWriter permiten realizar la lectura o escritura de un archivo respectivamente, para utilizarlas se debe agregar esta linea de codigo:

Imports System.IO             en VB
 Using System.IO;                en C#


StreamReader
La clase StreamReader se deriva de una clase abstracta denominada TextReader, que lee caracteres de una secuencia o archivo, pero en si esta clase no es de tipo  abstracta: es decir, que hay que declararla como objeto.

Para leer un archivo debemos asociar un StreamReader al mismo usando el método OpenText() de la siguiente forma:

 Dim leer As System.IO.StreamReader    ---> declaramos leer como variable
 leer = File.OpenText("ruta del archivo")   --->abrir archivo para la lectura

Una vez que tenemos nuestro StreamReader usaremos para leer el archivo los siguientes métodos:
  • ReadLine()
  • ReadToEnd()
Ambos métodos devuelven un tipo string. El método ReadLine() devuelve todos los caracteres hasta encontrar un fin de línea. ReadToEnd() devuelve un string conteniendo todo el archivo.
Una vez que terminamos con el archivo, hay que cerrarlo usando el método Close() del Stream.

Aqui un ejemplo básico que lee el texto de un archivo en una variable de cadena y muestra el texto en un RichTextBox:


Public Class Lectura
    Public Sub Leyendo()
        'declarar la clase como objeto(como variable) y que abra y lea
        'un archivo de texto de codificación UTF-8 y entre paréntesis va
        'la dirección y nombre del archivo en la path dada. 
        Dim bloc As New System.IO.StreamReader("ruta")
        'Luego se guarda el contenido en una variable del tipo cadena
        'Se muestra el contenido 
          RichTextBox1.Text = bloc.ReadToEnd()      
        'Se cierra el objeto
        bloc.Close()
    End Sub

End Class



también podría haberse usado Using pero depende de cada quien

 Using Dim bloc As New System.IO.StreamReader("ruta")
        RichTextBox1.Text = bloc.ReadToEnd()      
        'Se cierra el objeto
        End Using
    End Sub



ese ejemplo fué en VB, ahora otro en C# usando ReadLine() para sacar un promedio de notas, para esto debera leer linea por linea


using (StreamReader sr = new StreamReader("notas.txt"))

{
string linea;
double nota = 0;
count = 0;
while ((line = sr.ReadLine()) != null)
{
    nota += double.Parse (linea);
    count++;
}
promedio = (double)inValue / count;
}
Textbox1.Text=promedio;
} }



algo a notar es que algunas veces ya esta definida la ruta a buscar o algun usuario la pasa por correo o simplemente alguien o nosotros mismos la cambiamos sin darnos cuenta, entonces antes de relaizar cualquier accion, podemos verificar que la ruta dada exista, asi:
System.IO.File.Exists( file_name ) == true

IF(System.IO.File.Exists("ruta") == true)
Using Dim bloc As New System.IO.StreamReader("ruta")
        RichTextBox1.Text = bloc.ReadToEnd()      
        'Se cierra el objeto
        End Using
       End If    

      End Sub



StreamWriter
La clase StreamWriter se deriva de una clase abstracta denominada TextWriter, que escribe caracteres en una secuencia o archivo.

Ahora el ejemplo siguiente escribe una línea de texto en un archivo con StreamWriter

    Private Sub Escribiendo()
        Dim escritor As New System.IO.StreamWriter("c:\escrito.txt")
        escritor.WriteLine("esto es lo que hay")
        escritor.WriteLine()    'Linea en blanco
        escritor.Close()
    End Sub

El ejemplo siguiente agrega texto a un archivo existente, es decir, si ese fichero existe, lo que haremos es añadir más contenido, de forma que después de escribir, lo que tendrá será lo que antes hubiere más lo que ahora escribamos.

Para conseguir esto lo único que tenemos que hacer es indicar en el constructor de la clase StreamWriter un segundo argumento con un valor verdadero, de esa forma, si el fichero existe, se añadirá el texto al final de lo que ya tuviera. Si el fichero no existe, simplemente se creará y se guardará el texto actual, pero no dará error de que no existe.

Sub EscribeAbajo()
        Dim file As New System.IO.StreamWriter("c:\ejemplo.txt", True)
        file.WriteLine("esto acá es añadido")
        file.Close()
    End Sub


otro ejemplo sería este:



Using escritor As StreamWriter = New StreamWriter("ruta", True)
            escritor.WriteLine("voy primero")
        End Using

        ' 2: Append the second line
        Using escritor As StreamWriter = New StreamWriter("ruta", True)
            escritor.WriteLine("voy despues")
        End Using

la salida sería: voy primero
                      voy despues          



Codificación
Lo bueno con estas clases es que podremos acceder al contenido de los ficheros en modo texto a la vez que se puede indicar en el constructor de estas clases la codificación a usar, en .NET de forma predeterminada, el formato o codificación usado para leer o escribir en los ficheros es UTF-8 es decir caracteres Unicode de 8 bits, en VS si no indicamos lo contrario, los ficheros se leerán y se guardarán usando la codificación UTF-8, si solo se abrirán o escribirán archivos de texto para usarlos con aplicaciones .NET no habrá ningún problema, pero si  lo que tu guardes se puede abrir con cualquier otra aplicación de desarrollo, se debe tener cuidado con la codificación usada, sobre todo si el contenido tiene caracteres especiales, ya que en esos casos, el formato usado por defecto por otras aplicaciones para Windows no será el adecuado, y esos caracteres no se leerán correctamente.

Para evitar errores se debe usar la codificación predeterminada de Windows (ANSI), definida en el espacio de nombres System.Text y usando el valor Default, algo asi.


C#
System.IO.StreamReader lector = new System.IO.StreamReader(texto, System.Text.Encoding.Default);

VB
Dim lector As New System.IO.StreamReader(texto, System.Text.Encoding.Default)



otro ejemplo para el streanWriter es definir el tercer parámetro en Unicode para que StreamWriter codifique el archivo en Unicode, para no hacer larga la especificacion de la codificación, se importa el espacio de nombres Imports System.Text  y se tiene:

StreamWriter = New StreamWriter("ruta", True, Encoding.Unicode)

Si los ficheros solo se usarán desde aplicaciones de .NET o bien se van a guardar archivos XML se debe usar la codificación predeterminada, es decir: UTF-8.

Ejemplos StreamReader
por otro lado, si queremos leer ficheros escritos por otros programas que usan la codificación estándar de Windows, tal es el caso de los ficheros creados con Visual Basic 6.0, o NotePad, debemos indicar en el constructor de la clase StreamReader un segundo argumento que es la codificación que queremos usar, en este caso Encoding.Default, asi:

Visual Basic:

Using leer As New System.IO.StreamReader(ruta, Encoding.Default)

            RichTextBox1.text = leer.ReadToEnd()

        End Using



C#:

StreamReader leer;

using (leer = new System.IO.StreamReader(ruta,_ System.Text.Encoding.Default)){

richTextBox1.Text= leer.ReadToEnd();
}


Ejemplos StreamWriter
Para escribir en esa codificación (o en cualquier otra) tendremos que indicar la codificación a usar en el tercer argumento del constructor de la clase StreamWriter, ya que en el segundo debemos indicar si queremos agregar el texto a lo que ya tuviera o bien crear el fichero usando solo el contenido que queremos guardar.
 

En caso de que queramos crear un fichero con el contenido que tenemos en una variable, usaremos el siguiente código, fijarse que este codigo sobreescribe en caso que exista el archivo, por supuesto, si lo que queremos hacer es agregar el texto al fichero, en vez de usar false en el segundo argumento, debemos usar true.

Visual Basic:
Dim texto As String = "escribiendo codificado"

        Using escritor As New System.IO.StreamWriter(ruta, False, System.Text.Encoding.Default)

            escritor.WriteLine(texto)

        End Using



C#:
string texto = "escribiendo codificado";
StreamWriter escritor;
using (escritor = new System.IO.StreamWriter(ruta, false,_ Encoding.Default)){

escritor.WriteLine(texto);
}



Y si en vez de usar el valor "Default" queremos usar otro tipo de codificación, lo indicaremos en el tercer argumento, seleccionando uno de los valores de la clase Encoding:
  • ASCII
  • BigEndianUnicode
  • UTF7
  • UTF8