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();
|