Mostrando las entradas con la etiqueta Archivos. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Archivos. Mostrar todas las entradas

16 mayo, 2007

Leyendo y escribiendo archivos comprimidos

En días anteriores escribí acerca de cómo leer y escribir archivos, hoy quiero ampliar este tema explicando cómo manejar archivos comprimidos.

Para crear y abrir archivos comprimidos el namespace system.io nos facilita dos clases Gzipstream y el Deflatestream. Estas clases implementan el mismo algoritmo de compresión, la principal diferencia radica en que el Gzip almacena información adicional en el encabezado, esto provoca que los archivos comprimidos con Gzip sean un poco más grandes que los comprimidos con Deflate, pero, esto le permite ser más compatible. Ambos algoritmos limitados a archivos inferiores a 4gb.

Si vamos a comprimir un archivo que vamos a enviar a otras máquinas es recomendable utilizar el Gzip y no el Deflate. Pero veamos un ejemplo de cómo usar la clase GzipStream

Imports system.io

Imports System.IO.Compression

Module Module1

Sub Main()

Dim NombreArchivoOrigen As String = "c:\temp\log.txt"

Dim NombreArchivoComprimido As String = "c:\temp\log.txt.gz"

Dim ArchivoOrigen As FileStream = File.Open(NombreArchivoOrigen, FileMode.Open, FileAccess.Read)

Dim ArchivoDestino As FileStream = File.Open(NombreArchivoComprimido, FileMode.CreateNew, FileAccess.Write)

Dim MiStream As New GZipStream(ArchivoDestino, CompressionMode.Compress)

'Se utiliza integer en lugar de byte para poder almacenar -1.

Dim Mibyte As Integer = ArchivoOrigen.ReadByte()

While Mibyte <> -1

MiStream.WriteByte(CType(Mibyte, Byte))

Mibyte = ArchivoOrigen.ReadByte()

End While

MiStream.Close()

ArchivoOrigen.Close()

ArchivoDestino.Close()

Dim infoarchivoorigen As FileInfo = New FileInfo(NombreArchivoOrigen)

Dim infoarchivocomprimido As FileInfo = New FileInfo(NombreArchivoComprimido)

Console.WriteLine("Tamaño original : {0}", infoarchivoorigen.Length)

Console.WriteLine("Tamaño comprimido: {0}", infoarchivocomprimido.Length)

Console.ReadKey()

End Sub

End Module

Ahora, que si no queremos usar el Gzip sino el deflate solo requerimos de cambiar la clase GzipStream por DeflateStream el resto del procedimiento es igual, veamos:

Imports system.io

Imports System.IO.Compression

Module Module1

Sub Main()

Dim NombreArchivoOrigen As String = "c:\temp\log.txt"

Dim NombreArchivoComprimido As String = "c:\temp\log.txt.gz"

Dim ArchivoOrigen As FileStream = File.Open(NombreArchivoOrigen, FileMode.Open, FileAccess.Read)

Dim ArchivoDestino As FileStream = File.Open(NombreArchivoComprimido, FileMode.CreateNew, FileAccess.Write)

Dim MiStream As New DeflateStream(ArchivoDestino, CompressionMode.Compress)

'Se utiliza integer en lugar de byte para poder almacenar -1.

Dim Mibyte As Integer = ArchivoOrigen.ReadByte()

While Mibyte <> -1

MiStream.WriteByte(CType(Mibyte, Byte))

Mibyte = ArchivoOrigen.ReadByte()

End While

MiStream.Close()

ArchivoOrigen.Close()

ArchivoDestino.Close()

Dim infoarchivoorigen As FileInfo = New FileInfo(NombreArchivoOrigen)

Dim infoarchivocomprimido As FileInfo = New FileInfo(NombreArchivoComprimido)

Console.WriteLine("Tamaño original : {0}", infoarchivoorigen.Length)

Console.WriteLine("Tamaño comprimido: {0}", infoarchivocomprimido.Length)

Console.ReadKey()

End Sub

End Module

Ahora que ya sabemos cómo comprimir, debemos aprender a descomprimir, la lógica es la misma, solo debemos invertirla. Veamos:

Imports system.IO

Imports System.IO.Compression

Module Module1

Sub Main()

Dim NombreArchivoComprimido As String = "c:\temp\log.txt.gz"

Dim NombreArchivoDestino As String = "c:\temp\log.txt"

Dim ArchivoOrigen As FileStream = File.Open(NombreArchivoComprimido, FileMode.Open, FileAccess.Read)

Dim ArchivoDestino As FileStream = File.Open(NombreArchivoDestino, FileMode.CreateNew, FileAccess.Write)

Dim MiStream As New GZipStream(ArchivoOrigen, CompressionMode.Decompress)

Dim Mibyte As Integer = MiStream.ReadByte()

While Mibyte <> -1

ArchivoDestino.WriteByte(CType(Mibyte, Byte))

Mibyte = MiStream.ReadByte()

End While

MiStream.Close()

ArchivoOrigen.Close()

ArchivoDestino.Close()

Dim infoarchivoorigen As FileInfo = New FileInfo(NombreArchivoComprimido)

Dim infoarchivodestino As FileInfo = New FileInfo(NombreArchivoDestino)

Console.WriteLine("Tamaño comprimido : {0}", infoarchivoorigen.Length)

Console.WriteLine("Tamaño destino : {0}", infoarchivodestino.Length)

Console.ReadKey()

End Sub

End Module

El anterior ejemplo descomprime utilizando GZip si el archivo que deseamos descomprimir fue comprimido mediante Deflate solo tenemos que cambiar la clase y listo, el resto es exactamente igual.

14 mayo, 2007

Leyendo y escribiendo archivos

Stream

Esta clase nos brinda una serie de métodos para trabajar con datos secuenciales, además, se especializa según los datos con los cuales vamos a trabajar en:

FileStream

MemoryStream

CriptoStream

NetworkStream

GZipStream

Empecemos con el primero, el FileStream. Como su nombre lo indica permite hacer operaciones sobre los datos contenidos en los archivos. Lo primero que necesitamos conocer es como obtener el FileStream de un archivo, esto lo hacemos mediante la clase File:

Dim Miarchivo As FileStream = File.Open("c:\prueba.log", FileMode.Open, FileAccess.Read)

Sin embargo, para facilitar la lectura del archivo podemos utilizar el StreamReader ya que el FileStream lee el archivo como un arreglo de bytes, el StreamReader permite leer el archivo como un simple string. Veamos cómo podemos hacer esto:

Sub Main()

Dim Miarchivo As FileStream = File.Open("c:\prueba.log", FileMode.Open, FileAccess.Read)

Dim Mistreamreader As New StreamReader(Miarchivo)

Console.WriteLine(Mistreamreader.ReadToEnd())

Console.ReadKey()

End Sub

Mediante el OpenText de la clase File podemos simplificar el código anterior:

Sub Main()

Dim Mistreamreader As StreamReader = File.OpenText("c:\prueba.log")

Console.WriteLine(Mistreamreader.ReadToEnd())

Console.ReadKey()

End Sub

De igual forma podemos crear un nuevo archivo:

Sub Main()

Dim Mistreamwriter As StreamWriter = File.CreateText("c:\temp\prueba.log")

Mistreamwriter.WriteLine("Primera linea")

Mistreamwriter.WriteLine("Segunda linea")

Mistreamwriter.Close()

End Sub

Es importante tomar en cuenta que el fragmento de código anterior sobre escribe el archivo.

En algunas ocasiones es necesario crear el stream en memoria de manera temporal, antes de almacenarlo, por ejemplo, en un archivo. Para estos casos se puede utilizar el memorystream, su uso es muy similar al filestream. Veamos un ejemplo:

Sub Main()

Dim Mitemp As New MemoryStream()

Dim Mistream As StreamWriter = New StreamWriter(Mitemp)

Mistream.WriteLine("Primera Linea")

Mistream.WriteLine("Segunda Linea")

Mistream.WriteLine("Tercera Linea")

Mistream.Flush()

Dim Miarchivo As FileStream = File.Create("c:\temp\prueba.txt")

Mitemp.WriteTo(Miarchivo)

Mitemp.Close()

Mistream.Close()

Miarchivo.Close()

End Sub

Cuando necesitamos manejar stream que requieran gran velocidad contamos con el streambuffered, su uso es muy similar a los anteriores por lo cual solo lo voy a citar, en futuros artículos voy a comentar sobre los otros tipos de blogs.

10 mayo, 2007

Manejo de archivos, carpetas y unidades mediante system.io

Una de las actividades comunes al desarrollar es tratar con archivos, por eso quiero escribir un poco de las facilidades que .net Framework nos proporciona.

Lo primero que debemos conocer es el namespace system.io, el cual nos proporciona una serie de clases para el manejo de archivos, carpetas y hasta unidades completas.

Podríamos decir que system.io se divide en dos tipos de clases, las de información (derivadas de filesysteminfo) y las de utilidades (file, directory y path)

Pero, veamos como se utilizan, empecemos con FileInfo, este nos permite ver información de un archivo.

Imports System.IO

Module Module1 Sub Main()

Dim Mi_archivo As New FileInfo("c:\windows\explorer.exe")

Console.WriteLine("Directorio = {0}", Mi_archivo.DirectoryName)

Console.WriteLine("Nombre = {0}", Mi_archivo.Name)

Console.WriteLine("Extensión = {0}", Mi_archivo.Extension)

Console.WriteLine("Fecha de creación = {0}", Mi_archivo.CreationTimeUtc)

Console.WriteLine("Fecha última modificación = {0}",

Mi_archivo.LastWriteTimeUtc)

Console.ReadKey()

End Sub

End Module

Pero, el fileinfo además de brindarnos información de un archivo nos permite realizar algunas operaciones con él.

Mi_archivo.CopyTo("c:\winres\explorer.res", True)

Mi_archivo.MoveTo("c:\carpeta\respaldo.bak")

Otras clases importantes son las siguientes

Directory_info

Permite manipular directorios

DriveInfo

Permite manipular unidades de disco (isReady, TotalSize, TotalFreeSpace)

Path

Permite manejar rutas de archivos de forma más eficiente que si las manejáramos como simples cadenas de texto

FileSystemWatcher

Permite monitorear cambios (Creación, modificación, renombrado, borrado) el sistema de archivos y directorios.

En el siguiente ejemplo podemos ver como listar los archivos de una carpeta específica.

Sub Main()

Dim Mi_directorio As DirectoryInfo = New DirectoryInfo("c:\windows")

For Each Mi_archivo As FileInfo In Mi_directorio.GetFiles()

Console.WriteLine("Archivo: {0}, Tamaño: {1} bytes", Mi_archivo.Name, Mi_archivo.Length)

Next

Console.ReadKey()

End Sub