Almacenando Información en Java (Ficheiros)
Conceptos Básicos
Soporte, Organización e Acceso
Os Soportes
Un sistema informático xestiona a información almacenada na súa memoria RAM en formato binario, sendo procesada pola CPU para producir información nova que é almacenada de volta na memoria RAM do sistema. A memoria RAM é volátil, polo que si desconectamos o equipo a información almacenada se perde. Polo tanto é necesario almacenar a información binaria en algún tipo de soporte de información permanente.
Os soportes de almacenamento permanente máis utilizados son os soportes magnéticos, que nos últimos anos están sendo substituídos polas memorias SSD. En canto ao xeito en que permiten almacenar e recuperar a información, podemos clasificar os soportes de almacenamento en:
- Soportes Secuenciais: A información se almacena unha detrás de outra segundo vai chegando, non é posible retroceder nin avanzar a unha posición de escritura concreta sin pasar por enriba de información previa. Entre estes tipos de soporte podemos destacar as cintas magnéticas.
- Soportes de Acceso Aleatorio: Permiten acceder a posicións concretas do soporte de xeito directo para realizar operacións de lectura e escritura. De este tipo de soportes podemos destacar os Discos Magnéticos (HDD) ou as memorias de estado sólido (SDD).
Os dispositivos máis comúns de almacenamento utilizados polos programas son soportes de acceso aleatorio, principalmente HDD e SDD. O xeito de organizar a información en estes tipos de soporte é similar. Dende o punto de vista da programación o concepto máis importante é o de bloque físico.
O Sistema de Arquivos
Os soportes nos dan a posibilidade de almacenar información, pero para poder gardala e recuperala de un xeito eficiente necesitamos organizala dun xeito "comprensible". O xeito en que se organiza a información nun soporte para poder acceder á mesma con facilidade se coñece como sistema de arquivos.
Sistemas de arquivos de uso común son FAT32, VFAT, NTFS, EXT4, ZFS, BTRFS ... etc, cada un de eles con diferentes características e limitacións. Sen embargo, teñen algo en común: Almacenan a información en Ficheiros (ou Arquivos) e a organizan en Directorios (ou "carpetas"),
Un arquivo é o lugar onde almacenamos información en formato binario pertencente a un "concepto" concreto. Por exemplo podemos ter información dunha factura, un documento de texto, un vídeo ou unha fotografía. Podemos distinguir entre dous tipos de arquivos diferentes:
- arquivos de texto: Nos arquivos de texto a información binaria almacenada (nun arquivo informático e nos sistemas informáticos toda a información está sempre en binario, e decir representando únicamente valores 0 e valores 1) se interpreta como caracteres. Estes caracteres poden ser interpretados segundo varias codificacións (ISO, UTF-8, UTF-16) e algúns deles teñen un significado "especial" (como o salto de liña). Para interpretar correctamente un arquivo de texto é necesario coñecer que codificación de caracteres utiliza.
- arquivos binarios: Nos arquivos binarios a información non ten unha interpretación concreta. Son arquivos que conteñen bits que poden representar absolutamente calquera cousa: Un programa, unha canción, unha fotografía, .... etc. O modo en que se almacena a información se coñece como "formato" do arquivo. Formatos comúns son: class, EXE, PDF, MP4, AVI, MP3, OGG, DOC, MKV, .... etc. Habitualmente para que unha persoa recoñeza de inmediato o tipo de arquivo (o seu formato) se utiliza unha "extensión" para o nome do arquivo que consiste nun punto seguido de 3 letras. Os programas poden ter en conta esa extensión ou non facelo.
Os sistemas de arquivos organizan os arquivos en distintos directorios formando unha árbore na que o raíz ou inicio é o directorio / (\ en Windows). A partir de ahí se van creando directorios e subdirectorios formando unha árbore do tamaño que se desexe. En todos os directorios existen dous directorios "especiais". O directorio . que representa a posición actual, e o directorio .. que representa o directorio anterior ao actual.
Para referirnos a un directorio ou arquivo do sistema concreto necesitamos especificar o seu camiño ou ruta (path). O path pode ser:
- Relativo: Se van listando os directorios polos que necesitamos pasar ata alcanzar o destino contando dende a nosa posición actual. Se separará un directorio de outro utilizando o caracter / si utilizamos un sistema UNIX/Linux ou \ si utilizamos un sistema Windows.
- Absoluto: Se van listando os directorios polos que necesitamos pasar ata alcanzar o destino contando dende o raíz (e polo tanto o path absoluto sempre comeza por / ou por \ si estamos en Windows).
- URN: Os URN son "persistentes" no sentido que sempre identificarán o mesmo recurso.
- URL: Os URL non son necesariamente "persistentes" e ademáis de identificar un recurso proporcionan información sobre como acceder ao mesmo normalmente indicando o protocolo de acceso antes do identificador (file://, http:// ftp://)
Uso do sistema de arquivos en Java: A clase File
A clase File do API de Java nos permite todas as accións posibles sobre un sistema de arquivos, as principais son:
- Crear un Arquivo: createNewFile
- Crear unha Carpeta: mkdir / mkdirs
- Determinar si un arquivo ou carpeta existe: exists
- Eliminar un Arquivo ou Carpeta: delete
- Listar os arquivos dunha carpeta: list
- Renomear un arquivo ou unha carpeta: renameTo
- Obter atributos dun arquivo: isDirectory, isFile, isHidden, length, lastModified, canExecute, canRead, canWrite
- EXERCICIO
- Escribir un programa Java que amose un prompt path a carpeta actual > e nos permita movernos mediante o comando cd, crear directorios co comando md, crear arquivos co comando create listar os arquivos mediante o comando ls, renomear arquivos co comando ren e eliminar arquivos co comando rm. Tamén debe permitir obter o tamaño e a data de modificación dun arquivo ou directorio co comando info
A organización: Campos, Rexistros e Bloques
Cando almacenamos información dentro dun arquivo o modo de recuperala depende de varios factores, sendo os máis importantes o tipo de soporte no que se almacena a información (secuencial ou directo) e como se organiza a información dentro do propio ficheiro. A información que se almacena nun arquivo se divide habitualmente en rexistros. Un rexistro é un bloque de información con unha relación moi forte entre sí. Podemos comparalo ao conxunto de atributos de unha clase. Por exemplo si almacenamos nun ficheiro os nomes e notas dunha serie de alumnos o rexistro estaría composto do nome do alumno e da súa nota.
Cada unha das distintas informacións que compoñen o rexistro se coñece como campo. Facendo un símil, si considereamos que un rexistro é similar a un obxecto, un campo ten relación cun atributo.
Cando almacenamos datos nun ficheiro, os organizamos en modo de rexistros, que están compostos de campos.
Un bloque é o conxunto de rexistros que lemos ou escribimos de unha soa vez. Un bloque pode ser un único rexistro ou máis de un. O óptimo é que o tamaño do bloque coincida co tamaño do bloque físico que utilice o soporte.
Dependendo como sexan os rexistros podemos distinguir entre:
- Ficheiros con rexistro de lonxitude fixa: Todos os rexistros teñen o mesmo tamaño. Isto permite unha xestión máis simple e efectiva dos datos xa que podemos coñecer con antelación onde comeza cada rexistro almacenado no ficheiro.
- Ficheiros con rexistro de lonxitude variable: Cada rexistro pode ocupar un número distinto de bytes. Isto complica a xestión e o acceso directo a un rexistro concreto, pero aforra espazo no disco.
Dependendo do tipo de soporte que utilicemos podemos organizar a información de varios xeitos:
- Organización Secuencial: E o xeito de organizar a información mais simple e se pode levar a cabo sobre soportes secuenciais ou directos. Os datos se escriben secuencialmente, un detrás de outro segundo van chegando.
- Organización Directa: Os rexistros se almacenan nunha posición concreta derivada a partir do seu contido (hashing). É necesario un soporte de acceso directo e permite recuperar rapidamente o rexistro desexado. O problema principal desta organización é o potencial tamaño do arquivo (o ficheiro é tan grande como a posición do último rexistro) e a posibles colisións (cando a distintos rexistros se lles asigna a mesma posición)
- Organización Indexada: Se trata de gardar os datos nun soporte de acceso directo e crear un índice no que se asocia cada rexistro (normalmente mediante un valor único dun campo do rexistro denominado "chave primaria") coa posición en que está grabado. Isto permite localizar moi rápido os rexistros desexados.
O acceso
Acceso secuencial, directo e indexado
Serialización, A interface Serializable
A clase RandomAccessFile
O "punteiro do ficheiro", operacións "seek" e "getFilePointer"
Exercicio =
A partir de unha clase, crear un ficheiro que garde os datos e un índice que os localice por chave primaria. No arranque do programa se carga o índice na memoria nun map.
class Index<K> {
K key; long positition;
}