Assim como o projeto coin, não existe nenhuma grande novidade nessa especificação, no entanto agora é possível um trabalho mais simplificado com os I/Os no java. Com a classe java.nio.file.Files é possível fazer diversas operações de maneira simples, para esses processos ele usa a interface java.nio.file.Path que representa arquivos e diretórios do sistema operacional.


Path path=Paths.get("arquivo.txt");

Listagem 6. criando um path em que a String arquivo.txt pode ser substituído por qualquer caminho dentro do S.O seja ele diretório, arquivo ou até mesmo links simbólicos ou rígidos.


public static void movendoArquivo(Path arquivoOrigem, Path arquivoDestino) throws Exception {
 Files.move(arquivoOrigem, arquivoDestino, StandardCopyOption.REPLACE_EXISTING);
}

public static void copiandoArquivo(Path arquivoOrigem, Path arquivoDestino) throws Exception {
 Files.copy(arquivoOrigem, arquivoDestino, StandardCopyOption.REPLACE_EXISTING);
}

public static void deletandoArquivo(Path arquivo) throws Exception {
 Files.delete(arquivo);
}

public static Path criarArquivo(String arquivo) throws Exception {
 return Files.createFile(Paths.get(arquivo));
}

public static Path criarDiretorio(String diretorio) throws Exception {
 return Files.createDirectories(Paths.get(diretorio));
}

public static void criarLinkSimbolico(Path linkSimbolico, Path arquivo) throws Exception {
 Files.createSymbolicLink(linkSimbolico, arquivo);
}

public static void criarLinkRigido(Path link, Path arquivo) throws Exception {
 Files.createLink(link, arquivo);
}
Listagem 7. operações de I/Os simplificadas utilizando o java.nio.Files

É possível recuperar informações do java.nio.Path de uma forma bastante simples, além de ser possível obter tais informações na implementação de 6 novas interfaces. Na listagem 8 é mostrado o acessos dessas informações além da implementação de duas interfaces que exibe informações de um determinado caminho (Path).


public static void propriedadesPath(Path path) throws Exception {

    System.out.println("Tamanho do arquivo em bytes " + Files.size(path));
    System.out.println("é diretório " + Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS));
    System.out.println("é regular " + Files.isRegularFile(path, LinkOption.NOFOLLOW_LINKS));
    System.out.println("é escondigo pelo SO " + Files.isHidden(path));
    System.out.println("Modificacao " + Files.getLastModifiedTime(path, LinkOption.NOFOLLOW_LINKS));
    System.out.println("Dono " + Files.getOwner(path, LinkOption.NOFOLLOW_LINKS));

    System.out.println("\n \n \n Basicos Atributos do arquivo \n \n \n ");
    BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);

    System.out.println("criacao: " + attr.creationTime());
    System.out.println("ultmo acesso: " + attr.lastAccessTime());
    System.out.println("ultima modificacao: " + attr.lastModifiedTime());

    System.out.println("e diretorio: " + attr.isDirectory());
    System.out.println("isOther: " + attr.isOther());
    System.out.println("arquivo regular: " + attr.isRegularFile());
    System.out.println("simbolico link: " + attr.isSymbolicLink());
    System.out.println("tamanho: " + attr.size());

    System.out.println("\n \n \n Dos Atributos do arquivo \n \n \n ");

    DosFileAttributes dosAttr = Files.readAttributes(path, DosFileAttributes.class);
    System.out.println("somente leitura " + dosAttr.isReadOnly());
    System.out.println("escondido " + dosAttr.isHidden());
    System.out.println("arquivo " + dosAttr.isArchive());
    System.out.println("arquivo de sistema " + dosAttr.isSystem());
//As outras interfaces
//PosixFileAttributeView
//FileOwnerAttributeView
//AclFileAttributeView
//UserDefinedFileAttributeView
}
Listagem 8. obtendo informações de um caminho (Path)

Com o NIO2 a leitura e escrita de arquivos também pode ser escalável com o java.nio.channels.FileChannel, ou seja agora se pode ter vários canais dentro de um único arquivo, esse recurso pode ser muito interessante para a leitura de arquivos grandes no qual se pode dividir o trabalho entre duas ou três threads, na listagem é mostrado a leitura e escrita de do arquivo usando o FileChannel.


public static void acessoEscalavel(Path path) throws Exception {
 String s = "I was here!\n";
 byte data[] = s.getBytes();
 ByteBuffer out = ByteBuffer.wrap(data);

 ByteBuffer copy = ByteBuffer.allocate(12);

 try (FileChannel fc = (FileChannel.open(path,
    StandardOpenOption.READ, 
    StandardOpenOption.WRITE))) {
     //lendo os 12 primeiros bytes do arquivo
     int nread;
     do {
         nread = fc.read(copy);
         byte[] bytearr = copy.array();

         String ss = new String(bytearr);
         System.out.println("lendo: " + ss);

     } while (nread != -1 && copy.hasRemaining());

     //escrevendo a string no comeco do arquivo
     fc.position(0);
     while (out.hasRemaining()) {
         fc.write(out);
     }

     out.rewind();
     //movendo para o final do arquivo  copiado os 12 bytes
     //e no final do arquivo escrever novamente
     long length = fc.size();
     fc.position(length - 1);
     copy.flip();
     while (copy.hasRemaining()) {
         fc.write(copy);
     }
     while (out.hasRemaining()) {
         fc.write(out);
     }
 } catch (IOException x) {
     System.out.println("I/O Exception: " + x);
 }
}
Listagem 9. leitura de um arquivo a partir do FileChannel

Com o Path também é possível realizar a leitura e escrita da mesma forma que é possível com o java.io.File


public static void lendoArquivo(Path arquivo) throws Exception {
     Charset charset = Charset.forName("UTF-8");

     String strLine = null;
     try (BufferedReader reader = Files.newBufferedReader(arquivo, charset)) {

         while ((strLine = reader.readLine()) != null) {
             System.out.println("Arquivo " + strLine);
         }
     } catch (IOException x) {
         System.err.format("IOException: %s%n", x);
     }
 }
 public static void escrevendoArquivo(Path arquivo, String texto) throws Exception {
     Charset charset = Charset.forName("UTF-8");

     try (BufferedWriter writer = Files.newBufferedWriter(arquivo, charset)) {
         writer.write(texto, 0, texto.length());

     } catch (IOException x) {
        System.err.format("IOException: %s%n", x);
     }
 }
Listagem 10. Leitura e escrita de um arquivo com Path

Neste artigo foi explanado um pouco sobre o nio2, mostrando as grandes facilidades em processos de I/Os.