Home I/O com a NIO.2 API em Java
Post
Cancelar

I/O com a NIO.2 API em Java

Baseado nos cursos da Softblue

NIO.2 API x Legacy I/O API

  • O Java conta com uma API de I/O desde a sua primeira versão

– Esta API tem algumas limitações

  • A New I/O (NIO.2) API surgiu para resolver os problemas que a API legada possui

  • A NIO.2 API surgiu com o Java 7

  • A tendência é que ela substitua a API de I/O legada gradualmente

A interface Path

  • O sistema de arquivos define caminhos para diretórios e arquivos

  • Windows

C:\Users\Me\MyFile.txt

  • Unix

/home/me/Myfile.txt

  • Um objeto Path representa um caminho

– Pode ser de um arquivo ou diretório

– O arquivo ou diretório não precisam necessariamente existir

Manipulando objetos Path

  • A classe Paths possui métodos estáticos, que permitem manipular objetos Path
1
2
3
Path p = Paths.get("C:\\Users\\Me\\MyFile.txt");//Cria um objeto Path com base no caminho especificado

Path p = Paths.get("C:", "Users", "Me", "MyFile.txt");//Cria um objeto Path juntando partes do caminho
  • É comum haver situações onde dois ou mais objetos Path precisam ser juntados para gerar um Path completo
1
2
3
4
Path dir = Paths.get("/home/me");
Path file = Paths.get("MyFile.txt");
Path path = dir.resolve(file);
Path path = dir.resolve("MyFile.txt"); ///home/me/MyFile.txt

Métodos úteis da classe Paths

1
Path p = Paths.get("C:\\Users\\Me\\MyFile.txt");
MétodoRetorno
p.toString()“C:\Users\Me\MyFile.txt”
p.getFileName()“MyFile.txt”
p.getParent()“C:\Users\Me”
p.getNameCount()3
p.getName(1)“Me”
p.subPath(0, 2)“Users\Me”
p.getRoot()“C:"
1
Path p = Paths.get("files\MyFile.txt");
MétodoRetorno
p.toAbsolutePath()“C:\DiretorioCorrente\files\MyFile.txt”

A classe Files

  • Possui métodos estáticos que permitem manipular arquivos
1
2
Path path = Paths.get("/home/me/MyFile.txt")
boolean exists = Files.exists(path);//Verifica se o arquivo ou diretório existe
  • Outros métodos de Files
MétodoDescrição
isReadable(path)Permite leitura?
isWritable(path)Permite escrita?
isExecutable(path)Pode ser executado?
isDirectory(path)É um diretório?
isHidden(path)Está oculto?
size()Retorna o tamanho em bytes

Operações em arquivos e diretórios

  • Excluir
1
2
Files.delete(path);
Files.deleteIfExists(path);
  • Copiar
1
2
Files.copy(sourcePath, targetPath);
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
  • Mover
1
2
Files.move(sourcePath, targetPath);
Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);

Lendo e escrevendo dados

1
2
InputStream in = Files.newInputStream(path);//Arquivos binários
BufferedReader reader = Files.newBufferedReader(path);//Arquivos texto

InputStream e BufferedReadersão classes que fazem parte da API legada de I/O

1
2
3
byte[] bytes = Files.readAllBytes(path);
List<String> lines = Files.readAllLines(path);
//Recomendados para arquivos menores
1
2
OutputStream out = Files.newOutputStream(path);//Arquivos binários
BufferedWriter writer = Files.newBufferedWriter(path);//Arquivos texto

OutputStream e BufferedWriter são classes que fazem parte da API legada de I/O

1
2
3
Files.write(path, bytes);
Files.write(path, lines);
//Recomendados para arquivos menores

O enum StandardOpenOptions

  • Várias operações de manipulação de arquivos e diretórios solicitam parâmetros que definem o comportamento destas operações
Elemento do enumDescrição
WRITEArquivo para escrita.
APPENDFaz append de dados.
TRUNCATE_EXISTINGFaz o truncamento do arquivo.
CREATE_NEWCria um novo arquivo. Se ele existir, lança exceção.
CREATESe o arquivo existir, abre. Se não existir, cria.
DELETE_ON_CLOSEExclui o arquivo quando a stream é fechada.

Criando arquivos

  • Arquivos regulares
1
Path file = Files.createFile(path);
  • Arquivos temporários
1
2
Path file = Files.createTempFile("files_", ".temp");
//C:\Users\Me\AppData\Local\Temp\files_1365648452074156411.temp

Criando diretórios

  • Diretórios regulares
1
2
Path dir = Files.createDirectory(path);
Path dir = Files.createDirectories(path);//Cria vários níveis de diretórios
  • Diretórios temporários
1
2
Path dir = Files.createTempDirectory("temp_");
//C:\Users\Me\AppData\Local\Temp\temp_6589015846917767979

Conteúdo de um diretório

  • A interface DirectoryStream permite iterar sobre o conteúdo de um diretório
1
2
3
4
5
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
    for (Path path : stream) {
        //...
    }
}
  • É possível filtrar por padrões no nome
1
2
3
4
5
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.txt") {//Glob
    for (Path path : stream) {
        //...
    }
}

Para saber mais sobre o glob, consulte o javadoc de FileSystem.getPathMatcher()

Criando filtros de conteúdos

  • Nem sempre o uso do glob atende às necessidades de filtragem

– Ele se baseia apenas em padrões de nome

  • Nestes casos é preciso implementar um filtro customizado
1
2
DirectoryStream.Filter<Path> filter =file -> Files.isDirectory(file);// Expressão lambda para o método accept()
DirectoryStream<Path> s = Files.newDirectoryStream(dir, filter)) {

Iterando sobre a árvore de diretórios

  • A interface FileVisitor possui 4 métodos que devem ser implementados

preVisitDirectory()

postVisitDirectory()

visitFile()

visitFileFailed()

  • É possível também estender a classe SimpleFileVisitor

  • O método Files.walkFileTree() é chamado para iniciar a iteração

Watch Service API

  • Permite que a aplicação seja notificada quando um diretório ou arquivo é criado, excluído ou modificado
1
2
WatchService watcher = FileSystems.getDefault().newWatchService();
WatchKey key = dir.register(watcher,ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
  • Deve existir um loop na aplicação que fica recebendo os eventos

Integrando NIO.2 com a Legacy I/O API

  • Aplicações antigas (anteriores ao Java 7) não tiveram acesso à NIO.2 API

  • Para que estas aplicações não precisem ser reescritas, existe uma forma de integrar a API legada de I/O com a NIO.2 API

1
2
Path path = file.toPath();
File file = path.toFile();
Esta postagem está licenciada sob CC BY 4.0 pelo autor.