JavaNIO.2:MaisumaAPIparaI/O?
UMARÁPIDAINTRODUÇÃO
FranciscoOliveira
OzJUG-2016
WhoamI?
AnalistadeSistemas
● Iron Mountain do Brasil
TecnólogoemAnáliseeDesenvolvimentodeSistemas
● Fatec Ipiranga
Social
● delley.fx@gmail.com
● @delley_fx
● facebook.com/delley.fx
● github.com/delley
O que há de errado com
java.io.File?
● Faltadeinformação sobre o que está acontecendo
● Operações com arquivo nãosãoatômicas
● Semacessoemmassa para atributos dos arquivos
● Difilcudades para escalarlistagem de diretórios
● Faltam operações básicas
● Não é possível copiaratributos de um arquivo
Por que outra API para a
MANIPULAÇÃO de ARQUIVOS?
● Suporte limitado para metadadosdoarquivo
● Suporte limitado para linkssimbólicos
● Não há maneiras de estender a API para implementações
de sistemasdearquivoscustomizados
● Não há suporte para notificações
Por que outra API para a
MANIPULAÇÃO de ARQUIVOS?
OdesigndaAPINIO.2
Pacotes
● java.nio.file
● java.nio.file.attribute
● java.nio.file.spi
Path
● Um caminho no sistema de arquivos
Paths
● Fábrica de objetos Path (caminho)
Files
● Classe com métodos estáticos para operações mais comuns
FileSystems
● Fábrica de objetos FileSystem
FileStore
● Encapsula o sistema de armazenamento
AinterfacePath
●Representa um caminho absoluto ou relativo
●Iterável sobre elementos de um caminho
●Imutável
●Operações para:
 Acesso aos elementos de caminho
 Combinar caminhos
 Comparar caminhos
Criandoumcaminho
Path path =
FileSystems.getDefault().getPath("/foo");
Criandoumcaminho
Path path = Paths.get("/foo");
Criandoumcaminho
URI uri = URI.create("file:///foo");
Path path = Paths.get(uri);
Criandoumcaminho
File file = new File("/foo");
Path path = file.getPath();
Acessandoelementosdeumcaminho
Path path = Paths.get("/","foo","bar","x");
Path file = path.getFileName();
Path parent = path.getParent();
Path root = path.getRoot();
Path subpath = path.subpath(1,3);
Acessandoelementosdeumcaminho
Path path = Paths.get("/","foo","bar","x");
for (Path element : path ) {
System.out.format("%s%n", element);
}
Combinandocaminhos
Path foo = Paths.get("/", "foo");
Path bar = foo.resolve("bar");
Path baz = foo.resolveSibling("baz");
Path qux = Paths.get("/", "baz", "qux");
Path relative = foo.relativize(qux);
Testandocaminhos
Path path = Paths.get("top", "foo", "bar");
boolean isStart = path.startsWith("to");
boolean isEnd = path.endsWith("pot");
boolean isAbs = path.isAbsolute();
Outrasoperações
Path path = Paths.get("top", "foo", "bar");
Path normal = path.normalize();
Path abs = path.toAbsolutePath();
Path real = path.toRealPath();
URI uri = path.toUri();
File file = path.toFile();
AclasseFiles
● Métodos estáticas para trabalhar com arquivos
● A maioria das operações espera um Path como argumento
● Operações para:
 Leitura e Escrita de arquivos
 Streams, leitores (readers), escritores (writers)
 Links Simbólicos
 Trabalhar com diretórios
● Lança exceções significativas em caso de falha
Files:Operaçõesbásicas
Path file = Files.createFile(path);
Path dir = Files.createDirectory(pathDir);
Path dir = Files.createDirectories(pathDir);
Files:Operaçõesbásicas
import static
java.nio.charset.StandardCharsets.*;
List<String> lines = Files.readAllLines(file,
UTF_8);
byte[] bytes = Files.readAllBytes(file);
Files.delete(path);
Files.deleteIfExists(path);
Files.copy(source, target);
Files.copy(source, target, ATOMIC_MOVE,
REPLACE_EXISTING, COPY_ATTRIBUTES);
Files.move(source, target);
Files:Operaçõesbásicas
Files:Linkssimbólicos
Path link = Paths.get("top", "link");
Path target = Paths.get("top", "foo", "tar");
Files.createSymbolicLink(link, target);
boolean isSymLink = Files.isSymbolicLink(link);
boolean isSame = Files.isSameFile(link, target);
Path tar = Files.readSymbolicLink(link);
Leitura(reader)eescrita(Writer)
import static
java.nio.charset.StandardCharsets.*;
import java.nio.file.StandardOpenOption;
Path file = ...
BufferedReader reader =
Files.newBufferedReader(file, UTF_8);
BufferedWriter writer =
Files.newBufferedWriter(file, UTF_8,
StandardOpenOption.CREATE_NEW);
Streams
Path file = ...
InputStream is =
Files.newInputStream(file);
OutputStream os =
Files.newOutputStream(file);
OutputStream osAppend =
Files.newOutputStream(file, CREATE, APPEND);
Atributosdearquivo
● Metadados dos arquivos
● Exemplo:
 criado, atualizado, data do último acesso
 rwxr--r--
● Definido pela plataforma e sistemas de arquivos
Atributosdearquivo
BasicFileAttributes
● Suportado por todas as plataformas
● Datas (criação, modificação, último acesso), tipo
arquivo, tamanho, chave do arquivo
DosFileAttributes
● Oculto, arquivo, somente leitura, sistema
PosixFileAttributes
● Dono, grupo, conjunto de permissões
Atributosdearquivo
BasicFileAttributes basicAttr =
Files.readAttributes(path,
BasicFileAttributes.class);
String key = basicAttr.fileKey();
long size = basicAttr.size();
boolean isDirectory = basicAttr.isDirectory();
FileTime lastModified =
basicAttr.lastModifiedTime();
Atributosdearquivo
PosixFileAttributes posixAttr =
Files.readAttributes(path,
PosixFileAttributes.class);
UserPrincipal owner = posixAttr.owner();
GroupPrincipal group = posixAttr.group();
String perms =
PosixFilePermissions.toString(
posixAttr.permissions()));
Files.setPosixFilePermissions(path,
PosixFilePermissions.fromString("rwxrwxrwx"));
ListagemdeDiretório
● Iteração eficiente na listagem de diretórios
● Escalabilidade para grandes diretórios, sistemas de
arquivos remotos, etc.
● Suporta filtros:
 Glob
 Regex
 Filtros personalizados
ListagemdeDiretórios
try (DirectoryStream<Path> dirStream =
Files.newDirectoryStream(dir,"*.java")) {
for (Path path : dirStream) {
format("%s%n", path.toAbsolutePath());
}
}
ListagemdeDiretório
DirectoryStream.Filter<Path> filter =
new DirectoryStream.Filter<Path>() {
public boolean accept(Path entry)
throws IOException {
return Files.size(entry) > 1024;
}
};
try (DirectoryStream<Path> dirStream =
Files.newDirectoryStream(dir,filter)) {
...
}
Percorrendoárvoresdediretórios
● Implementa o PadrãoVisitor para percorrer árvores de
diretórios
● Files.walkFileTree (start, fileVisitor)
 start: nó incial
 fileVisitor: define operaçõe que serão realizadas
● Travessia em profundidade
Percorrendoárvoresdediretórios
● Métodos callbacks de FileVisitor:
 preVisitDirectory
 visitFile
 postVisitDirectory
 visitFileFailed
● Enum FileVisitResult
 CONTINUE
 TERMINATE
 SKIP_SUBTREE
 SKIP_SIBLINGS
Percorrendoárvoresdediretórios
Path start = Paths.get("/foo/bar");
Files.walkFileTree(start, new SimpleFileVisitor<Path>(){
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs) throws IOException {
format("preVisitDirectory: %s%n", dir);
return FileVisitResult.CONTINUE;
}
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
format("visitFile: %s%n", file);
return FileVisitResult.CONTINUE;
}
});
WatchService
● Monitora mudanças
 Criar, atualizar, excluir
● Usa notificações nativas
WatchService
WatchService watcher =
FileSystems.getDefault().newWatchService();
Path dir = …
WatchKey watchKey = dir.register(watcher,
ENTRY_MODIFY);
WatchService
boolean keepWatching = true;
while(keepWatching){
WatchKey key = watcher.poll(10,
TimeUnit.SECONDS);
for (WatchEvent<?> event: key.pollEvents()) {
if (event.kind() == ENTRY_MODIFY) {
Path name = (Path) event.context();
...
}
}
key.reset();
}
WatchService
PontosaobservarnoMundoReal
● Sub-diretórios não são monitorados
● Alguns editores criam um novo arquivo ao atualizar
 Esperamos uma ATUALIZAÇÃO, mas recebemos um
evento EXCLUIR + CRIAR
● Alguns sistemas de arquivos criam inicialmente um
arquivo com zero bytes
 Esperamos um evento de CRIAR, mas observamos um
CRIAR + ATUALIZAÇÃO
Sistemadearquivospersonalizado
● Permite a criação de sistemas de arquivos personalizados
 FileSystemProvider
● Sistema de arquivos em memória
● O Provedor de sistema de arquivo Zip é fornecido como
uma implementação de referência
Consideraçõesfinais
● NIO.2 funciona de forma consistente em todas as
plataformas
● Suporta novas operações
● Suporta o acesso em massa para atributos de arquivo
● Exceções melhores
● SPI para a interface de provedores de sistemas de
arquivos personalizados
OBRIGADO!!!

Java NIO.2: Mais uma API para I/O?