Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Leer datos de archivo binario

717 views
Skip to first unread message

Saga

unread,
May 11, 2010, 12:54:21 PM5/11/10
to
Saludos. En esta ocasion tengo un archivo que contiene datos, tales como
numeros, fechas y bytes. Desarrolle el siguiente codigo para leer esta
informaicon:

Dim TheBytes() As Byte
Dim strNombre As String = ""
Dim bytHeader(3) As Byte
Dim bytByte As Byte
Dim lngTimeStamp As Integer
Dim bytExtra(1) As Byte
Dim intFH As Integer

On Error GoTo ehUncompressFile


intFH = FreeFile()

FileOpen(intFH, strArchivoDatos, OpenMode.Binary)

FileGet(intFH, (bytHeader))


If bytHeader(0) = 225 And bytHeader(1) = 179 Then

'Consigue la fecha y hora (num de segundos desde fecha en 1970).
FileGet(intFH, lngTimeStamp)

'Lee otros 2 bytes.
FileGet(intFH, (bytExtra))

If (bytHeader(3) And 16) = 16 Then

'Consigue el nombre.
Do
FileGet(intFH, bytByte)

If bytByte > 0 Then
strNombre = strNombre & Chr(bytByte)
End If
Loop Until bytByte = 0
End If


ReDim TheBytes(CInt(LOF(intFH) - 1))

FileGet(intFH, (TheBytes))

Basicamente, leo una cabecaera de 4 bytes, reviso que la "llave" sea la
correcta en los primeros dos bytes. Si lo es, consigo 4 bytes que tienen
una fecha y hora y otros dos byte, luego si el 5o bit del cuarto byte esta
puesto (-1) entonces consigo un nombre. Por fin el leo resto de los datos
a un arreglo (The Bytes)

Esta rutina la converti de otra en VB6 y estaba probada y funcionando
bien, solo que hoy que regrese a hacer algunas pruebas finales me
encuentro que no esta funcoinando. La primera instruccion de lectura
que lee los 4 bytes al arreglo byeCabecera() solo lee ceros. Ya revise
el archivo y efectivamente estan ahi los primeros 4 bytes tal como los
espero. No se porque ahora esta leyendo ceros. Cualquier orientacion
es bienvenida, o bien un metodo alterno mas confiable para poder
realizar la equivalente funcion. Gracias, Saga


SoftJaén

unread,
May 13, 2010, 8:57:05 AM5/13/10
to
Hola, Saga:

No sabr�a decirte donde est� el problema. Pero ya que est�s utilizando
Visual Basic .NET, prueba a utilizar un objeto BinaryWriter (para escribir
en un archivo binario) y un objeto BinaryReader (para su posterior lectura).
Ambas clases se encuentran dentro del espacio de nombres System.IO, espacio
que deber�s de importar en tu proyecto.

Por ejemplo, vamos a guardar en un archivo binario, un entero de 4 bytes
(Integer), seguidos de los ticks de una fecha cualquiera (un valor Long), y
a continuaci�n, una cadena alfanum�rica (String):

Imports System.IO

' Creamos un nuevo archivo binario con
' permisos de escritura.
'
Dim st As Stream = _
File.Open("C:\Temp\Archivo.dat", _
FileMode.Create, FileAccess.Write)

' Creamos un objeto BinaryWriter que lo
' asociaremos a la secuencia del archivo.
'
Using bw As New BinaryWriter(st)

' Escribimos un valor entero.
'
Dim n As Integer = 12345
bw.Write(n)

' Escribimos la fecha y hora actual, o mejor dicho, los
' Ticks correspondientes a la fecha y hora actual.
'
bw.Write(DateTime.Now.Ticks)

' Escribimos una valor alfanum�rico
bw.Write("�Hola, Mundo!")

' Cerramos los objetos
bw.Close()
st.Close()

End Using

Como sabemos el orden de los datos, significa que sabemos los tipos de datos
que contienen. Por tanto, bastar�a con utilizar los m�todos ReadXXX de un
objeto BinaryReader:

' Creamos una secuencia para leer el archivo binario
'
Dim st As Stream = _
File.Open("C:\Temp\Archivo.dat", _
FileMode.Open, FileAccess.Read)

' Creamos un objeto BinaryReader que lo
' asociaremos a la secuencia del archivo.
'
Using br As New BinaryReader(st)

' Leemos el primer valor que sabemos
' que es un Integer
'
Dim n As Integer = br.ReadInt32()

Debug.WriteLine(n)

' Leemos los Ticks de la fecha
'
Dim fecha As DateTime = New DateTime(br.ReadInt64)

Debug.WriteLine(fecha)

' Leemos el valor alfanum�rico
Dim s As String = br.ReadString()

Debug.WriteLine(s)

' Cerramos los objetos
br.Close()
st.Close()

End Using

Mira a ver si de �sta manera puedes leer tu archivo binario.

Un saludo

--
Enrique Mart�nez
[MS MVP - VB]

Nota informativa: La informaci�n contenida en este mensaje, as� como el
c�digo fuente incluido en el mismo, se proporciona �COMO EST��, sin
garant�as de ninguna clase, y no otorga derecho alguno. Usted asume
cualquier riesgo al poner en pr�ctica, utilizar o ejecutar lo recomendado o
sugerido en el presente mensaje.

Saga

unread,
May 13, 2010, 2:47:37 PM5/13/10
to
Muchas gracias SoftJa�n!

La solucion que encontre fue remover los parentesis que le puse al
nombre del arreglo de bytes:

FileGet(intFH, (bytHeader)) 'No funciona

FileGet(intFH, bytHeader) 'Si funciona

El problema se presento cuando decidi configurar Option Strict ON.

Aun asi, otros que he consultado me han recomendado no usar fileget()
y los otros comandos de esta familia. Mi objetivo es cambiar a usar el
binary reader, tal como recomiendas.

Una pregunta mas... veo que usas el estatuto "Using". Aunque lo he
buscado varias veces y visto ejemplos de su uso, aun no me queda
completamente claro para que se usa. Segun entiendo, su unico
uso es para crear bloques de codigo donde la variable que se
declara dentro del estatuto using sea local a ese bloque. Por
ejemplo, puedo hacer esto:

for i as integer = 0 to 10
x = x
next i

La variable i solo es valida dentro del bloque del for.

using i as integer
for i = 0 to 10
x = x
next i
end using

Este bloque seria equivalente al anterior con respecto al
alcance de i. �Es correcto como estoy viendo esto? De nuevo
gracias! Saga

"SoftJa�n" <grupo_n...@softjaen.es> wrote in message
news:2CD71436-445C-435B...@microsoft.com...
> Hola, Saga:
>
> No sabr�a decirte donde est� el problema. Pero ya que est�s utilizando


> Visual Basic .NET, prueba a utilizar un objeto BinaryWriter (para escribir
> en un archivo binario) y un objeto BinaryReader (para su posterior
> lectura).
> Ambas clases se encuentran dentro del espacio de nombres System.IO,
> espacio

> que deber�s de importar en tu proyecto.


>
> Por ejemplo, vamos a guardar en un archivo binario, un entero de 4 bytes
> (Integer), seguidos de los ticks de una fecha cualquiera (un valor Long),
> y

> a continuaci�n, una cadena alfanum�rica (String):


>
> Imports System.IO
>
> ' Creamos un nuevo archivo binario con
> ' permisos de escritura.
> '
> Dim st As Stream = _
> File.Open("C:\Temp\Archivo.dat", _
> FileMode.Create, FileAccess.Write)
>
> ' Creamos un objeto BinaryWriter que lo
> ' asociaremos a la secuencia del archivo.
> '
> Using bw As New BinaryWriter(st)
>
> ' Escribimos un valor entero.
> '
> Dim n As Integer = 12345
> bw.Write(n)
>
> ' Escribimos la fecha y hora actual, o mejor dicho, los
> ' Ticks correspondientes a la fecha y hora actual.
> '
> bw.Write(DateTime.Now.Ticks)
>

> ' Escribimos una valor alfanum�rico
> bw.Write("�Hola, Mundo!")


>
> ' Cerramos los objetos
> bw.Close()
> st.Close()
>
> End Using
>
> Como sabemos el orden de los datos, significa que sabemos los tipos de
> datos

> que contienen. Por tanto, bastar�a con utilizar los m�todos ReadXXX de un


> objeto BinaryReader:
>
> ' Creamos una secuencia para leer el archivo binario
> '
> Dim st As Stream = _
> File.Open("C:\Temp\Archivo.dat", _
> FileMode.Open, FileAccess.Read)
>
> ' Creamos un objeto BinaryReader que lo
> ' asociaremos a la secuencia del archivo.
> '
> Using br As New BinaryReader(st)
>
> ' Leemos el primer valor que sabemos
> ' que es un Integer
> '
> Dim n As Integer = br.ReadInt32()
>
> Debug.WriteLine(n)
>
> ' Leemos los Ticks de la fecha
> '
> Dim fecha As DateTime = New DateTime(br.ReadInt64)
>
> Debug.WriteLine(fecha)
>

> ' Leemos el valor alfanum�rico


> Dim s As String = br.ReadString()
>
> Debug.WriteLine(s)
>
> ' Cerramos los objetos
> br.Close()
> st.Close()
>
> End Using
>

> Mira a ver si de �sta manera puedes leer tu archivo binario.
>
> Un saludo
>
> --
> Enrique Mart�nez
> [MS MVP - VB]
>
> Nota informativa: La informaci�n contenida en este mensaje, as� como el
> c�digo fuente incluido en el mismo, se proporciona �COMO EST��, sin
> garant�as de ninguna clase, y no otorga derecho alguno. Usted asume
> cualquier riesgo al poner en pr�ctica, utilizar o ejecutar lo recomendado

SoftJaén

unread,
May 13, 2010, 6:42:01 PM5/13/10
to
"Saga" escribi�:

>
> La solucion que encontre fue remover los parentesis que
> le puse al nombre del arreglo de bytes:
>
> FileGet(intFH, (bytHeader)) 'No funciona
>
> FileGet(intFH, bytHeader) 'Si funciona
>
> El problema se presento cuando decidi configurar
> Option Strict ON.

�Claro! Es que si tienes activada la instrucci�n Option Strict On (que es lo
recomendable), no puedes pasar una matriz a la funci�n FileGet, cuyo segundo
par�metro del tipo System.Array se encuentra definido �por referencia�
(ByRef), ya que se puede dar una restricci�n al cargar de nuevo el par�metro
System.Array en la matriz definida del tipo Byte, de ah� que tengas que
encerrar entre par�ntesis el argumento de llamada, para pasarlo �por valor�
(ByVal). Y puede ser que al pasar el array por valor no te funcione. Tienes
que activar Option Strict On y utilizar un objeto BinariReader, que para eso
estamos en .NET. :-)

> Una pregunta mas... veo que usas el estatuto "Using". Aunque lo he
> buscado varias veces y visto ejemplos de su uso, aun no me queda
> completamente claro para que se usa. Segun entiendo, su unico
> uso es para crear bloques de codigo donde la variable que se
> declara dentro del estatuto using sea local a ese bloque. Por
> ejemplo, puedo hacer esto:
>
> for i as integer = 0 to 10
> x = x
> next i
>
> La variable i solo es valida dentro del bloque del for.
>
> using i as integer
> for i = 0 to 10
> x = x
> next i
> end using
>
> Este bloque seria equivalente al anterior con respecto al

> alcance de i. �Es correcto como estoy viendo esto?

No, en ning�n caso es equivalente, ni tampoco se puede usar una variable
Integer, Long, String, etc., para definir un bloque Using ... End Using.

En el bloque For ... Next, el �mbito de la variable �i� ser�a el propio
bloque donde se encuentra declarada. E igual �mbito de visibilidad tendr�a
dentro del bloque Using si el tipo de dato de la variable declarada
implementara la interfaz System.IDisponsable, que es el requisito que debe
de cumplir el tipo de dato de la variable que se defina en un bloque Using
... End Using. Pero los tipos de datos b�sicos no implementan IDisponsable,
al igual que otras muchas clases del marco de trabajo de .NET, por tanto,
obtendr�s una excepci�n en tiempo de dise�o.

El utilizar un bloque Using es porque de �sta manera nos aseguramos de que
al final se llamar� autom�ticamente al m�todo Dispose del objeto declarado,
con lo que se destruir� el objeto. Podemos obviar la instrucci�n Using y
efectuar una llamada expl�cita al m�todo Dispose del objeto, pero hay que
acordarse de hacerlo, y muchas veces, como que no nos acordamos de hacerlo,
y es recomendable y hasta necesario porque estamos trabajando con apertura y
cierre de archivos, que en el argot de .NET se tratan de �recursos no
administrados�, por tanto, no est�n en manos del �recolector de elementos no
utilizados� y hay que destruirlos expresamente para liberarlos.

--
Enrique Mart�nez
[MS MVP - VB]

Nota informativa: La informaci�n contenida en este mensaje, as� como el

c�digo fuente incluido en el mismo, se proporciona �COMO EST��, sin

garant�as de ninguna clase, y no otorga derecho alguno. Usted asume
cualquier riesgo al poner en pr�ctica, utilizar o ejecutar lo recomendado o

Saga

unread,
May 14, 2010, 11:04:58 AM5/14/10
to
Gracias por la informacion otorgada. Se agradece el tiempo que tomaste
en redactarla. Me ha sido muy util, considerando que en ningun lugar
encontre una explicacion tan sencilla y concisa.

Este pasado 12 de Febrero fue mi primer encuentro con el mundo de
.NET. Lo he encontrado fascinante, pero no sin sus detalles. El
problema mas grande con el que me he topado es determinar la
mejor practica para realizar alguna funcion que se puede hacer
usando sintaxis tomado directamente de VB6. Un ejemplo pudiera
ser el uso de la funcion fileget(). Este metodo funciona, aunque se
que no es la tecnica mas recomendada. Hasta esta semana que
pregunte es que me recomendaron el uso del lector binario. Espero
implementar y documentar esta informacion para que no quede en el
olvido. De nuevo, gracias.

Saludos! Saga


0 new messages