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
C:\Users\Me\MyFile.txt
/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étodo | Retorno | 
|---|
| 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étodo | Retorno | 
|---|
| 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
 | 
| Método | Descriçã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
1
2
  | Files.delete(path);
Files.deleteIfExists(path);
  | 
1
2
  | Files.copy(sourcePath, targetPath);
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
  | 
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 enum | Descrição | 
|---|
| WRITE | Arquivo para escrita. | 
| APPEND | Faz append de dados. | 
| TRUNCATE_EXISTING | Faz o truncamento do arquivo. | 
| CREATE_NEW | Cria um novo arquivo. Se ele existir, lança exceção. | 
| CREATE | Se o arquivo existir, abre. Se não existir, cria. | 
| DELETE_ON_CLOSE | Exclui o arquivo quando a stream é fechada. | 
Criando arquivos
1
  | Path file = Files.createFile(path);
  | 
1
2
  | Path file = Files.createTempFile("files_", ".temp");
//C:\Users\Me\AppData\Local\Temp\files_1365648452074156411.temp
 | 
Criando diretórios
1
2
  | Path dir = Files.createDirectory(path);
Path dir = Files.createDirectories(path);//Cria vários níveis de diretó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()
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
 
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();
  |