Guardar y abrir datos de un Array
Un nuevo ejercicio de Objetos. Consiste en: usando Objetos y sobrecarga de métodos y operadores, hacer un programa que guarde los datos de varias personas (FASE 1). Se podrá buscar personas por Nif y Nombre. Novedad: los datos de las personas se podrán guardar en un archivo. También tendrá una opción de recuperar esos datos (se pueden guardar en un archivo binario o de texto) (FASE 2). La lógica del contenido se meterá dentro de una clase. Así será independiente del formulario y se puede emplear para otras necesidades (FASE 3). La FASE 1 se hace como otras veces. Creamos un ArrayList como hace unos días. Las otras fase sí necesitremos esta ayuda. Para guardar los datos en un archivo meteremos un MenuStrip en el formulario (con Abrir, Guardar…). También tendremos que meter un OpenFileDiagog (ofd) y un SaveFileDialog (sfd). Así aparece en el botón “Guardar”. 'Así guardará los datos en el Escritorio. Podría ser en MyDocuments, etc. sfd.InitialDirectory = My.Computer.FileSystem.SpecialDirectories.Desktop 'Guarda todos los registros de la colección en un archivo. sfd.ShowDialog() 'Abre el control de guardar archivo. 'Si deseamos calcelar, hacemos lo siguiente. El cancel directo funciona mal. If sfd.ShowDialog = Windows.Forms.DialogResult.Cancel Then Exit Sub 'Se calcela y termina. End If 'PASOS PARA GUARDAR UN ARCHIVO. Pasos: ' 1. Se crea un flujo de escritura asociado al archivo. ' IMPORTANTE: tiene un 2º parámetro que puede valer True o False. Se presupone False. Con True, si no existe archivo, se creará; si existe, se añadirán datos al final. Si es False, exista archivo o no, se crea uno nuevo y se pierde su contenido previo. ' Recibe como parámetro la ruta del archivo. Dim Archivo As New StreamWriter(sfd.FileName) 'Para probar el TRUE. Quitaríamos el ShowDialog para que sobreescriba (con False) o añada datos (con True). 'Dim Archivo As New StreamWriter("C:\datos.txt", True) 'Nota: Si al principio, evitamos poner el Imports System.IO, aquí deberíamos poner: Dim Archivo As New System.IO.StreamWriter(sfd.FileName) ' 2. Ahora recorremos los Item de la coelcción y los guardamos en el archivo. For Each p In Personas 'Escribimos cada campo de una persona como una línea de texto en el archvo. 'Nuestro FLUJO se llama... Archivo Archivo.WriteLine(p.nif) 'NOTA: Si ponemos Write simplemente, los agregará en el archivo de forma consecutiva: esto posiblemente producirá errores ya que confundiría unos datos con otros. Archivo.WriteLine(p.Nombre) Archivo.WriteLine(CStr(p.Edad)) Next ' 3. Se cierra el Archivo. Archivo.Close() ' 4. Se libera el DTA (memoria RAM que consume) del Archivo. Archivo.Dispose() 'COMENTARIO: Marcas que son invisibles en un archivo de texto: ' Cuando se hace un fin de línea = <EOL> ' <EOF> = Fin de archivo End Sub Para el botón “Abrir” (para abrir un archivo creado con anterioridad) ponemos: ofd.InitialDirectory = My.Computer.FileSystem.SpecialDirectories.Desktop ofd.ShowDialog() Dim Archivo As New System.IO.StreamReader(ofd.FileName) Dim Contenido As String = Archivo.ReadToEnd() MsgBox(Contenido) Archivo.Close() Archivo.Dispose() Si en el MenuStrip metemos el botón “Abrir la colección”, metemos lo mismo. Emplearemos 2 técnicas (después del FileName y antes del Close): 1ª técnica: 'Ahora borro la colección. Personas.Clear() Dim Linea As String Linea = Archivo.ReadLine() 'Hacer Hasta Linea vale Nothing. Cuando Linea vale Nothing, termina. Do Until Linea Is Nothing 'Lee linea antes del bucle. MsgBox(Linea) Linea = Archivo.ReadLine() 'Lee la siguiente Linea. ' A esta técnica se le llama LECTURA ADELANTADA. Loop La otra técnica es así: Do While Archivo.EndOfStream <> True ' LECTURA RETRASADA. 'MsgBox(Archivo.ReadLine(), Archivo.ReadLine(), CByte(Archivo.ReadLine())) 'Para probar. Personas.Add(New Persona(Archivo.ReadLine(), Archivo.ReadLine(), CByte(Archivo.ReadLine()))) Loop 'Otra técnica: LECTURA RETRASADA. EndOfStream retorna True cuando llega al final del archivo. 'Do While Archivo.EndOfStream <> True ' "Hacer Mientras no llegue al final del archivo". ' Linea = Archivo.ReadLine() ' MsgBox(Linea) 'Loop