Java7. NIO2

Jun 24, 2014 | TIC-tek

Nio2, permite un enfoque basado en buffer y canales. Es un nuevo componente aparecido en Java 7. Es un formato asíncrono.

Los buffer son objetos que contienen datos y los canales son los dispositivos propiamente dichos como un archivo o socket. Para usar este sistema, normalmente se obtiene un buffer de datos para guardar los datos  y generar la entrada y salida y un canaEditarl para enviarlos.

El paquete java.nio.file y el paquete java.nio.file.attribute proporcionan soporte de entrada y salida para el acceso por defecto del sistema. Esto, no sustituye al paquete java.io sino que da funcionalidad añadida. Es bastante intuitivo y de fácil uso.

Java NIO proporciona funcionalidad  para:

  • El acceso a  estructuras de directorio a través de la clase Path.
  • Métodos para manipular Ficheros como, copiar, borrar o mover , además de devolver propiedades de los ficheros a través de la clase Files.
  • Podemos obtener información sobre el sistema de ficheros a través de la clase FileSystem.

Un sistema de ficheros organizado en uno o más discos duros se organizan en estructuras jeráquicas. El nivel más alto son los nodos que contienen subniveles de directorios o ficheros.

Path

Un fichero es identificado por un path en la  estructura de ficheros. Las distintas rutas para acceder a estos ficheros pueden ser relativas o absolutas.

Rutas Relativas

A partir del directorio actual se realizan las búsquedas de directorios.No se incluye el directorio raíz.  Por ejemplo, si estamos en la ruta C:/Raiz/bin y queremos volver al directorio raíz podemos utilizar caracteres como «..», los caracteres tradicionales de búsquedas de directorios.

Rutas Absolutas

En la búsqueda de directorios ,  a partir de de rutas absolutas, se incluye toda la ruta donde se encuentra el fichero correspondiente. C:/raiz/…

Clase Path

Introducida en el paquete JavaSE7, se encuentra en el paquete java.nio.file.  Esta clase es la representación de los path o rutas en el sistema de ficheros.El objeto Path contiene métodos para localizar, examinar y manipular ficheros.

El Path en Solaris, se especifica a través del carácter «/raiz/bin» , mientras que en Windows , la búsqueda  se hace con «raiz\bin».

Creación de un Path

Un Path, contiene información para especificar la localización de un fichero o directorio. La estructura de directorios debe de ser incluida para poder hacer la creación. La clase Path , proporciona los siguientes métodos:

Métodos

Definición

ToString()

Retorna la ruta del Path

getFileName() Retorna el nombre de la última secuencia de elementos
getName(0)

Retorna la ruta de elementos correspondiente al índice específicada

getNameCount Retorna el número de elementos del Path
subPath(0,2) Retorna la secuencia del path , no incluye el elemento root
getParent Retorna el directorio padre
getRoot Retorna el elemento root

 

Un ejemplo sería el siguiente suponiendo como Path c:/temp/Ejemplo en Windows.

public class Ejer_Pathpublic static void main(String[] args) {              Accecedemos a un Path              Path p1 = Paths.get("c:\\temp\\ejemplo");              System.out.println(p1.toString());              System.out.println(p1.getFileName());              System.out.format("getName(0): %s%n", p1.getName(0));              System.out.format("getNameCount: %d%n", p1.getNameCount());              System.out.format("subpath(0,2): %s%n", p1.subpath(0,2));              System.out.format("getParent: %s%n", p1.getParent());              System.out.format("getRoot: %s%n", p1.getRoot());        } }
Convertir un Path

Se puede usar un método para convertir un string en un objeto que pueda ser abierto por el navegador. El método toUri, proporciona esta funcionalidad.

System.out.format("%s%n", p1.toUri());

La salida por pantalla sería la siguiente:

file:///c:/temp/ejemplo

El método toRealPath retorna el path real de un fichero existente. Este método ejecuta operaciones como:

  • Si el path es relativo , devuelve el path absoluto
  • Si el Path contiene elementos redundantes, retorna el path con esos elementos eliminados.

Este método lanza una excepción, un ejemplo sería como los siguiente:

try {
    Path p2 = p1.toRealPath();
    System.out.println("RealPath: "+p2);
} catch (NoSuchFileException x) {

     System.err.format("%s: no  encontrado" + " fichero o directorio", p1);
     // Logic for case when file doesn't exist.
     ...
} catch (IOException x) {
     System.err.format("%s%n", x);
     // Logic for other sort of file error.
     ...
}

 

La visualización del ejemplo sería:

RealPath: C:\TEMP\ejemplo

Enlazar dos Path

Se pueden combinar dos Path, usando el método resolve(). Se pueden pasar rutas parciales, no incluidas en la ruta actual y añadirlas al Path. Estando en la ruta c:\temp\ejemplo incluimos la ruta añadida.

System.out.println( p1.resolve("añadida"));

 

Comparar dos Path

La clase Path soporta el método equals, con lo que es posible comparar dos Path. No obstante esta clase proporciona los métodos startsWith y endWith para comprobar el principio y fin de una cadena.

Un ejemplo de este método sería el siguiente:

System.out.println("Valor del Path p2: "+p2); if(p2.startsWith(Paths.get("temp"))||p2.endsWith(Paths.get("añadida"))){                    System.out.println("encontraste la ruta"); }

El resultado sería:

Valor del Path p2: c:\temp\ejemplo\añadida encontraste la ruta

Borrar un fichero o Directorio

Se puede borrar un fichero, directorio o link. La clase File del método delete(path) permite borrar un fichero o directorio de la cadena especificada.

Un ejemplo sería el siguiente:

try {    Files.delete(p2);    System.out.println("ruta borrada"); } catch (NoSuchFileException x) {

Otra opción, es el método deleteIfExists(Path) que borra un fichero, pero si el fichero no existe lanza una excepción.

Metada y Propiedades de Ficheros

Podemos saber los permisos, el directorio, la fecha de creación y el propietario a través de distintos métodos.

Métodos

Definición

Size(path)

Retorna el tamaño en bytes

isDirectory(path,linkOption)

Retorna true si el fichero especificado en el Path , se encuentra

isHidden(Path) Retrona true si el fichero está oculto para el sistema
getLastModifiedTime(Path, LinkOption…)

setLastModifiedTime(Path,

Retorna o modifica la fecha de la última modificación del fichero.
subPath(0,2) Retorna la secuencia del path , no incluye el elemento root
getOwner(Path,LinkOption…)
setOwner(Path, UserPrincipal)
Retorna o modifica el propietario
getPosixFilePermissions(Path, LinkOption…)
setPosixFilePermissions(Path, Set<PosixFilePermission>)
Retorna o modifica los permisos de un fichero en caracteres Posix.

 

Atributos básicos de un fichero

Para poder ver los atributos de un fichero , es posible usar la clase Files.readAttributes,  que devuelve una colección de tipo BasicFileAttribute que tiene las propiedades básicas de un fichero. Un ejemplo sería el siguiente:

       System.out.println("Propiedades de un Fichero");        Path p3 = Paths.get("c:\\temp\\ejemplo\\fichero.txt");        BasicFileAttributes attr = Files.readAttributes(p3, BasicFileAttributes.class);        System.out.println("Fecha de Creación: " + attr.creationTime());        System.out.println("Ultima Fecha de acceso: " + attr.lastAccessTime());        System.out.println("Última fecha de modificación: " + attr.lastModifiedTime());        System.out.println("isDirectorio: " + attr.isDirectory());        System.out.println("isFichero  Regular: " + attr.isRegularFile());        System.out.println("isSymbolicLink: " + attr.isSymbolicLink());        System.out.println("size: " + attr.size()); 
Modificar propiedades fecha de creación del fichero

Es posible modificar las propiedades de tiempo de un fichero de esta manera:

 long currentTime = System.currentTimeMillis();        FileTime ft = FileTime.fromMillis(currentTime);        Files.setLastModifiedTime(p3, ft);        System.out.println("Última fecha de modificación: " + attr.lastModifiedTime());
Permisos de los ficheros a través de Posix

Posix es un acrónimo de Portable Operating System Interface para Unix y sistemas operativos estándar, además de IEEE.

A través  de la clase PosixFileAttributes.class y PosixFilesPermision podemos obtener los permisos de un fichero. Los métodos de la clase Posixfiles Permision son:

Métodos

Definición

fromString() Acepta los String como permisos, devolviendo los permisos en su formato correspondiente.

 

Podemos ver los permisos de un fichero , de la siguiente forma:

ToString() Convierte los permisos a un String
System.out.println("********Permisos fichero***********");        PosixFileAttributes attr2 =                  Files.readAttributes(p3, PosixFileAttributes.class);        System.out.format("%s %s %s%n",                  attr2.owner().getName(),                  attr2.group().getName(),                  PosixFilePermissions.toString(attr2.permissions()));        } }

Modificar un Fichero o su Group Owner

Se puede dar permisos a un fichero a través de un usuario o de un grupo de usuarios.De tal manera, que con el método LookupPrincipalByName se puede dar permiso a un usuario concreto, o LookupPrincipalGroupName se da permisos a través de un grupo.

La forma sería de la siguiente manera:

GroupPrincipal grupo =  p2.getFileSystem().getUserPrincipalLookupService()         .lookupPrincipalByGroupName("cursoJava"); Files.getFileAttributeView(p2, PosixFileAttributeView.class)      .setGroup(group);

Leer, escribir y crear ficheros

Nio2 permite además la manipulación de ficheros a través de la clase File y el método newBufferedReader que crea un objeto de tipo Buffered para generar entrada-salida.

Los pasos para hacer esto serían:

  • Crear un Buffer
  • rear Canales
  • Utilizar la clase File

La clase BufferedReader tiene parámetros denominados OpenOptions donde indicamos el formato en el que se abre un fichero.

Tiene la siguientes posibilidades:

Métodos

Definición

WRITE Abre el fichero en modo escritura
APPEND Permite añadir nuevas filas al fichero

TRUNCATE_EXISTING

Trunca el fichero a 0 bytes
CREATE_ NEW

Crea un nuevo fichero lanzando una excepción si ya existe.

CREATE Abre el fichero si existe y si no existe lo crea
DELETE_ON_CLOSE Borrar el fichero cuando el Stream es cerrado

 

Escribir en ficheros

Existe la posiblidad de escribir en fichero a través del método write de la clase File. A write(path,buffer) se le pasa el Path y un array de bytes de tal manera que el resultado sería el siguiente:

byte[] buf = "esto es una prueba 2".getBytes();    Files.write(p3, buf);

 

Leer  ficheros

Existe la posiblidad de escribir en fichero a través del método write de la clase File. A write(path,buffer) se le pasa el Path y un array de bytes de tal manera que el resultado sería el siguiente:

Charset charset = Charset.forName("US-ASCII"); try (BufferedReader reader = Files.newBufferedReader(p3, charset)) {            String line = null;            while ((line = reader.readLine()) != null) {                System.out.println(line);       }  } catch (IOException x) {            System.err.format("IOException: %s%n", x);  }

 

Creación de   ficheros

Se puede crear un fichero vacío con un conjunto de atributos iniciales usando createFile(path,fileAttribut)e. Si el fichero existe se lanza una excepción. A continuación se muestra un ejemplo:

Path p4 = Paths.get("c:\\temp\\ejemplo\\fichero4.txt"); try {     Files.createFile(p4); } catch (FileAlreadyExistsException x) {     System.err.format("Error el fichero existe"); } catch (IOException x) {     System.err.format("Error de permisos sobre el fichero"); }
Ficheros Acceso Aleatorio

De manera estándar y a través del paquete Java.io, también existe la posibilidad de acceder a los ficheros de manera no secuencial. La clase ByteBuffer proporciona métodos para mover el puntero y dintintas partes del fichero y la interface SeekableByteChannel que implementa la clase FileChanel proporciona métodos para leer y escribir de manera aleatoria. Algunos  los métodos disponibles son los siguientes:

 

Métodos

Definición

position

Retorna la posición actual del cursor
Positon(long) Modifica la posición
Read(byteBuffer) Lee los bytes del buffer
Write(byteBuffer) Escribe en el buffer
Truncate(long)

Trunca el fichero correspondiente.

 

public class Prueba{   public static void main(String[] args) throws IOException{      RandomAccessFile File = new RandomAccessFile("prueba.txt", "r");      FileChannel inChannel = File.getChannel();      ByteBuffer buff = ByteBuffer.allocate(1024);      while(inChannel.read(buffer) > 0){        buff.flip();        for (int i = 0; i < buff.limit(); i++){           System.out.print((char) buff.get());        }        buff.clear();
     }      inChannel.close();      File.close();    } }

Catálogo 2023

Conoce nuestra oferta formativa para este año

Últimas entradas