Upload
lorraine-jug
View
2.077
Download
1
Embed Size (px)
DESCRIPTION
Citation preview
2
Architecte logiciel Java/.Net
Auteur de deux didacticiels diffusés sous la licence GNU FDL : http://www.jmdoudoux.fr Développons en Java (2330 pages) Développons en Java avec Eclipse (600 pages)
Rédacteur pour developpez.com,
Membre du Yajug et du CA du Lorraine Jug
Qui suis-je ?
NIO2
FileSystem API
Lectures/écritures : API mises à jour
Canaux asynchrones (Asynchronous I/0)
Conclusion
3
Plan
4
NIO 2
5
Le manque d’opérations basiques (copie, déplacement de fichiers, …)
Ne fonctionne pas de la même manière sur toutes les plateformes
Support limité des liens symboliques et des méta-données
…
Les défauts de java.io
6
Encapsule le chemin et les opérations
Gestion de certaines erreurs : certaines méthodes renvoient un booléen sans lever d’exceptions (delete() par exemple)
Manque de performance de certaines méthodes notamment listFiles()
…
=> besoin d’une nouvelle API
Les défauts de la classe File
7
Spécification JSR 203
JSR 203 : http://www.jcp.org/en/jsr/detail?id=203
8
NIO 2
JSR 203 : ajout de nouvelles API au package NIO
Accès et manipulation du système de fichiers
Mise à jour de l’API existante
Canaux asynchrones (asynchronous channels)
Inclus dans Java SE 7
9
FileSystem API
10
FileSystem API
API moderne, complète et extensible
Package java.nio.file et sous packages
Accès et gestion des systèmes de fichiers (fichiers, répertoires, liens symboliques)
Support des méta-datas
Parcours des répertoires
Extensible pour fournir sa propre implémentation (sous classe de FileSystem)
11
L’API FileSystem
12
Les principaux nouveaux concepts
Path : encapsule un chemin dans le système de fichiers
Files : méthodes statiques pour des opérations sur les fichiers et les répertoires
FileSystem : encapsule un système de fichiers, fabrique d’objets pour y accéder
FileSystems : fabrique d’instances de FileSystem
FileStore : encapsule le système de stockage sous jacent
13
L’interface Path
14
L’interface Path
Encapsule tout ou partie du chemin d’un élément du système de fichiers
Dépendant du système de fichier
Le chemin encapsulé existe ou non
Immuable
Chemin encapsulé absolu ou relatif
Pas de gestion des extensions des fichiers
Implémente Iterable et Comparable
15
L’interface Path
Création à partir d’un String, URI ou java.io.File
La classe helper Paths Paths.get("monfichier.txt");
Paths.get("jm/AppData/Local/Temp/monfichier.txt");
Paths.get("C:/Users/jm/AppData/Local/Temp/monfichier.txt");
Paths.get("C:\\Users\\jm\\AppData\\Local\\Temp\\monfichier.t
xt");
Paths.get(URI.create("file:///C:/Users/jm/AppData/Local/Temp
/monfichier.txt"));
Paths.get(System.getProperty("java.io.tmpdir"),
"monfichier.txt");
FileSystems.getDefault().getPath("logs", "access.log");
16
L’interface Path : gérer les éléments du chemin
Nombreuses méthodes pour gérer les éléments hiérarchiques du chemin
Path getFileName() : nom du dernier élément
Path getParent() : chemin parent ou null
Path getRoot() : racine du chemin ou null
Path subPath(int, int) : sous chemin
Path getName(int) : élément à l’index fourni
int getNameCount() : nombre d’éléments dans le chemin
17
L’interface Path : exemple
toString() = C:\Users\jm\AppData\Local\Temp\monfichier.txt
getFileName() = monfichier.txt
getRoot() = C:\
getName(0) = Users
getNameCount() = 6
getParent() = C:\Users\jm\AppData\Local\Temp
subpath(0,3) = Users\jm\AppData
toString() = jm\AppData\Local\Temp\monfichier.txt
getFileName() = monfichier.txt
getRoot() = null
getName(0) = jm
getNameCount() = 5
getParent() = jm\AppData\Local\Temp
subpath(0,3) = jm\AppData\Local
18
L’interface Path : manipuler des chemins
Plusieurs méthodes pour manipuler les chemins
Path normalize() : supprime les éléments redondants (par exemple . et ..), purement syntaxique
Path resolve(Path) : combiner deux chemins
Path relativize(Path) : chemin relatif entre le chemin et celui fournit
19
L’interface Path : manipuler des chemins
path = Paths.get("C:/Users/admin/
./../jm/AppData/Local/Temp/./monfichier.txt");
System.out.println("normalize() = " + path.normalize());
normalize() = C:\USers\jm\AppData\Local\Temp\monfichier.txt
Path path = Paths.get("C:/Users/jm/AppData/Local/");
Path nouveauPath = path.resolve("Temp/monfichier.txt");
System.out.println(nouveauPath);
nouveauPath = path.resolve("C:/Temp");
System.out.println(nouveauPath);
C:\Users\jm\AppData\Local\Temp\monfichier.txt
C:\Temp
20
L’interface Path : comparer des chemins
Plusieurs méthodes pour comparer les chemins
int compareTo(Path other) Compare le chemin avec celui fourni en paramètre
boolean endsWith(Path other) boolean endsWith(String other) Compare la fin du chemin avec celui fourni
boolean startsWith(Path other) boolean startsWith(String other) Compare le début du chemin avec celui fourni
21
L’interface Path : convertir des chemins
Plusieurs méthodes pour convertir les chemins
Path toAbsolutePath() : retourner le chemin absolu du chemin
Path toRealPath(LinkOption…) : retourner le chemin physique du chemin notamment en résolvant les liens symboliques selon les options fournies. Exception si le fichier n’existe pas ou s’il ne peut pas être accédé
22
L’interface Path : intégration dans l’existant
Path File.toPath()
File Path.toFile()
URI Path.toUri() : retourner le chemin sous la forme d’une URI
23
Glob
Pattern à appliquer sur un élément du système de fichiers
Sous ensemble des expressions régulières : * ** ? [] {} \
*.java éléments dont le nom fini par .java
??? éléments dont le nom est composé de trois alphanumériques
A*.java éléments dont le nom commence par un a et se termine par .java
*[0-9]* éléments dont le nom contient au moins un chiffre
*.{htm,html} éléments dont le nom se termine par htm ou html
24
Glob : exemple
Path file1 = Paths.get("c:/test.java");
Path file2 = Paths.get("c:/test.txt");
PathMatcher matcher =
FileSystems.getDefault().getPathMatcher("glob:*.{java,cla
ss}");
matcher.matches(file1);
matcher.matches(file2);
25
La manipulation des fichiers et des répertoires
26
La classe Files
Ensemble de méthodes statiques
Création : createDirectory(), createFile(), createLink(), createSymbolicLink(), createTempFile(), createTempDirectory(), …
Manipulation : delete(), move(), copy(), …
Type d’élément : isRegularFile(), isDirectory(),…
Méta-Datas et permissions : getAttributes(), getPosixFilePermissions(), isReadable(), isWriteable(), size(), getFileAttributeView(), …
27
Exemple : supprimer un fichier (1/2)
Path path = Paths.get("C:/java/test/monfichier_copie.txt");
try {
Files.delete(path);
} catch (NoSuchFileException nsfee) {
// traitement en cas d’erreur
} catch (DirectoryNotEmptyException dnee) {
// traitement en cas d’erreur
} catch (IOException ioe) {
// traitement en cas d’erreur
}
28
Exemple : supprimer un fichier (2/2)
Path path = Paths.get("C:/java/test/monfichier_copie.txt");
try {
Files.deleteIfExists(path);
} catch (DirectoryNotEmptyException dnee) {
// traitement en cas d’erreur
} catch (IOException ioe) {
// traitement en cas d’erreur
}
29
Exemple : déplacer un fichier
Path source = Paths.get("c:/java/source.txt");
Path cible = Paths.get("c:/temp/cible.txt");
try {
Files.move(source, cible, REPLACE_EXISTING, ATOMIC_MOVE);
// java.lang.UnsupportedOperationException
// Files.move(source, cible, REPLACE_EXISTING,
// COPY_ATTRIBUTES, ATOMIC_MOVE);
} catch(IOException ioe) {
// traitement en cas d’erreur
}
30
Exemple : copier un fichier
Path source = Paths.get("c:/java/fichier.txt");
Path cible = Paths.get("c:/java/fichier_copie.txt");
try {
Files.copy(source, cible, REPLACE_EXISTING,
COPY_ATTRIBUTES);
// java.lang.UnsupportedOperationException
// Files.move(source, cible, REPLACE_EXISTING,
// COPY_ATTRIBUTES, ATOMIC_MOVE);
} catch(IOException ioe) {
// traitement en cas d’erreur
}
31
Les liens symboliques
32
Les liens symboliques
Support optionnel selon le FS (Unix)
Liens symboliques suivis par défaut avec quelques exceptions : delete(), move(), walkFileTree()
Files.isSameFile() permet de vérifier si deux chemins font référence au même endroit
Files.isSymbolicLink()
Files.readSymbolicLink()
33
Exemple : créer un lien
Path lien = Paths.get("C:/java/test/monlien");
Path cible = Paths.get("C:/java/test/monfichier.txt");
Files.createLink(lien, cible);
if (Files.isSameFile(lien, cible)) {
System.out.println("Identique");
} else {
System.out.println("Non identique");
}
34
Exemple : créer un lien symbolique
Path lien = Paths.get("/home/jm/monlien");
Path cible = Paths.get("/home/jm/monfichier.txt");
Files.createSymbolicLink(lien, cible);
if (Files.isSameFile(lien, cible)) {
System.out.println("Identique");
} else {
System.out.println("Non identique");
}
35
L’interface WatchService
36
WatchService
Notifications de changements dans un répertoire
Evite d’avoir à écrire du code de type pooling sur un répertoire
Abonnement à des événements lors de la création, modification, suppression de fichiers
37
WatchService : enregistrement
Instanciation avec FileSystem.newWatchService()
Enregistrement avec WatchService.register()
WatchService watcher =
FileSystems.getDefault().newWatchService();
Path dir = Paths.get("c:/java");
WatchKey key = dir.register(watcher, ENTRY_CREATE)
38
WatchService : obtenir les événements
for (;;) {
try {
key = watcher.take();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
for (WatchEvent<?> event : key.pollEvents()) {
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
Path name = (Path) event.context();
System.out.format(event.kind() + " " + "%s created", name);
}
}
key.reset();
}
39
Les méta-données
40
Les attributs
Gestion complète des attributs qui sont dépendantes du système sous jacent
Taille, type d’élément, caché, …
Attributs communs (BasicFileAttributes)
ou attributs spécifiques (DosFileAttributes, PosixFileAttributes)
Gestion des permissions Posix
Méthodes de la classe Files pour en modifier un
41
Les attributs DOS
Path fichier = Paths.get("c:/java/test.txt");
FileTime now =
FileTime.fromMillis(System.currentTimeMillis());
Files.setLastModifiedTime(fichier, now);
Files.setAttribute(fichier, "dos:hidden", true);
DosFileAttributes attr = Files.readAttributes(fichier,
DosFileAttributes.class);
System.out.println(attr.isReadOnly());
System.out.println(attr.isHidden());
System.out.println(attr.isRegularFile());
System.out.println(attr.isSystem());
System.out.println(attr.lastModifiedTime());
42
Les attributs Posix
Path fichier = Paths.get("/home/jm/test.txt");
PosixFileAttributes attrs = Files.readAttributes(fichier,
PosixFileAttributes.class);
UserPrincipal owner = attrs.owner();
GroupPrincipal group = attrs.group();
System.out.println(owner);
System.out.println(group);
43
La gestion des droits Posix
Énumération PosixFilePermission
PosixFilePermissions : helper
FileAttribute : encapsule les attributs
Attention aux restrictions de droits via umask ou via le répertoire parent
Path fichier = Paths.get("/home/jm/test.txt");
Set<PosixFilePermission> perms =
PosixFilePermissions.fromString("rw-rw-rw-");
FileAttribute<Set<PosixFilePermission>> attr =
PosixFilePermissions.asFileAttribute(perms);
Files.createFile(fichier, attr);
44
Les attributs via les vues
Les vues permettent d’obtenir les attributs en bloc
Les vues sont spécialisées
Readonly ou mutable
45
Les attributs via les vues
AttributeView
FileAttributeView
BasicFileAttributeView
DosFileAttributeView
PosixFileAttributeView
FileOwnerAttributeView
AclFileAttributeView
PosixFileAttributeView
UserDefinedFileAttributeView
FileStoreAttributeView
46
Exemple avec BasicFileAttributView
Path fichier = Paths.get("c:/java/test.txt");
BasicFileAttributeView view =
Files.getFileAttributeView(fichier,
BasicFileAttributeView.class);
BasicFileAttributes attributes = view.readAttributes();
FileTime creationTime = attributes.creationTime();
FileTime lastAccessTime = attributes.lastAccessTime();
boolean isRegularFile = attributes.isRegularFile();
47
La classe FileStore
48
La classe FileStore
Encapsule un système de stockage : un disque dur, une partition, …
Obtenir des informations
FileStore Files.getFileStore(Path)
49
La classe FileStore : exemple
Path path = Paths.get("c:/test.txt");
FileStore store = Files.getFileStore(path);
long total = store.getTotalSpace() / (1024 * 1024);
long used = (store.getTotalSpace() –
store.getUnallocatedSpace()) / (1024 * 1024);
Long avail = store.getUsableSpace() / (1024 * 1024);
System.out.println("total "+total+" mb ");
50
La classe FileSystem
51
La classe FileSystem
Encapsule un système de fichiers
Obtenir celui du système par défaut ou invoquer une fabrique
FileSystem fs = FilesSystems.getDefault();
Utiliser une fabrique pour obtenir une implémentation spécifique
Fabrique pour des objets de l’API
Extensible : possibilité de créer sa propre implémentation
class MonFileSystem extends FileSystem();
52
Le séparateur du système de fichiers
String separateur = File.separator;
String separateur = FileSystems.getDefault().getSeparator();
53
Les providers de FileSystem
Il est possible d’utiliser ou de créer des fournisseurs de FileSystem
N’ont pas besoin d’être lié à un « vrai » système de fichiers
Peut permettre d’offrir différentes vues d’un système de fichiers (cacher les fichiers sensibles, accès un lecture seule, …)
java.nio.file.spi
54
Un provider FileSystem pour les zip
Permet de traiter le contenu d’un zip comme un FileSystem
Facilite l’utilisation des archives de type zip
55
Exemple : afficher un fichier d’un zip
Path jarfile = Paths.get("c:/java/archive.jar");
FileSystem fs = FileSystems.newFileSystem(jarfile, null);
Path mf = fs.getPath("META-INF", "MANIFEST.MF");
try (BufferedReader readBuffer =
Files.newBufferedReader(mf, Charset.defaultCharset())) {
String ligne = "";
while ((ligne = readBuffer.readLine()) != null) {
System.out.println(ligne);
}
}
56
Exemple : extraire un fichier d’un zip
Path jarfile = Paths.get("c:/java/archive.jar");
FileSystem fs = FileSystems.newFileSystem(jarfile, null);
Path cible = Paths.get("c:/java/MANIFEST.MF");
Files.deleteIfExists(cible);
// extaire un élément de l'archive
Files.copy(fs.getPath("/META-INF/MANIFEST.MF"), cible);
57
L’interface DirectoryStream
58
La classe DirectoryStream
Itération sur le contenu d’un répertoire
Performance sur un gros répertoire, consomme moins de ressources
Possibilité d’appliquer un filtre en utilisant un glob ou une expression régulière
Invoquer la méthode close() après utilisation
59
La classe DirectoryStream : exemple
Path dir = Paths.get("C:/java/projets");
try (DirectoryStream<Path> stream =
Files.newDirectoryStream(dir, "*.java")) {
for (Path entry : stream) {
System.out.println(entry.getFileName());
}
}
60
WalkFileTree
61
WalkFileTree
Parcourir une arborescence en utilisant le design pattern visitor (opérations récursives)
Files.walkFileTree()
FileVisitor invoqué sur chaque fichier / répertoire (pre/post)
SimpleFileVisitor : contrôle du parcours par la valeur de retour (CONTINUE, PRUNE)
Liens symboliques non suivis par défaut (FOLLOW_LINKS) : détection des références circulaires
62
WalkFileTree : exemple
Path dir = Paths.get("C:/java/projets");
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
String nom = file.getFileName().toString();
if (nom.endsWith(".java")) {
System.out.println("Fichier : " + nom);
}
return FileVisitResult.CONTINUE;
}
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs) throws IOException {
System.out.println("Repertoire : " + dir);
return FileVisitResult.CONTINUE;
}
});
63
Lectures / écritures
Mises à jour de l’API
64
IO
Java 1.0
Synchrone
Bloquant
File InputStream OutputStream Reader Writer Socket RandomAccessFile
La gestion des io avec Java
NIO
Java 1.4 (JSR 51)
Synchrone
Non bloquant
FileChannel SocketChannel ServerSocketChannel (Charset, Selector, ByteBuffer)
NIO 2
Java 7 (JSR 203)
ASynchrone
Non bloquant
Path
AsynchronousFileChannel AsynchronousByteChannel AsynchronousSocketChannel AsynchronousServerSocketChannel
65
Obtenir des flux
Path path = Paths.get("c:/java/source.txt");
BufferedReader reader = Files.newBufferedReader(path,
Charset.defaultCharset());
BufferedWriter writer = Files.newBufferedWriter(path,
Charset.defaultCharset());
InputStream inputStream = Files.newInputStream(path);
OutputStream outputStream = Files.newOutputStream(path);
ByteChannel channel = Files.newByteChannel(path);
66
L’utilisation des méthodes
67
Lire et écrire tout le contenu
byte[] bytes = Files.readAllBytes(path);
List<String> lignes = Files.readAllLines(path,
Charset.defaultCharset());
Files.write(path, bytes);
Files.write(path, lignes, Charset.defaultCharset());
68
Exemple : écriture dans un fichier texte
Path file = Paths.get("c:/java/test/test.txt");
Charset charset = Charset.forName("UTF8");
String contenu = "Prix 10€";
try (BufferedWriter writer = Files.newBufferedWriter(file,
charset)) {
writer.write(contenu, 0, contenu.length());
} catch (IOException ioe) {
// traitement de l'erreur
}
69
L’interface SeekableByteChannel
ByteChannel qui gère une position
Channel équivalent à RandomAccessFile
Files.newSeekableByteChannel()
CREATE, CREATE_NEW, READ, WRITE, APPEND, TRUNCATE_EXISTING, NOFOLLOW_LINKS, SYNC, DSYNC...
70
L’interface SeekableByteChannel : exemple
ByteBuffer donneesBonjour = ByteBuffer.wrap("Bonjour".getBytes());
ByteBuffer donneesBonsoir = ByteBuffer.wrap("Bonsoir".getBytes());
Path path = Paths.get("C:/java/fichier.bin");
Files.deleteIfExists(path);
try (FileChannel fileChannel = FileChannel.open(path,
StandardOpenOption.CREATE, StandardOpenOption.WRITE,
StandardOpenOption.SYNC)) {
fileChannel.position(100);
fileChannel.write(donneesBonjour);
}
try (SeekableByteChannel sbc = Files.newByteChannel(path,
StandardOpenOption.WRITE, StandardOpenOption.SYNC)) {
sbc.position(200);
sbc.write(donneesBonsoir);
}
71
Canaux asynchrones
(Asynchronous I/0)
72
Canaux asynchrones
Channel avec opérations non bloquantes (connexion, lecture, écriture)
Exécution des opérations de manière asynchrone (dans un thread)
Contrôle des opérations après leur initialisation via deux solutions :
java.util.concurrent.Future
java.nio.channels.CompletionHandler
73
Canaux asynchrones avec Future
Utiliser l’objet de type Future pour connaitre le statut et le résultat de l’opération
Future.get() : obtenir le résultat (bloquant!)
Future.get() : avec un timout
Future.isDone() : l’opération est elle terminée
Future.cancel(boolean) : annuler l’opération
74
Canaux asynchrones avec CompletionHandler
Callback qui sera invoqué lorsque l’opération se termine (bien ou mal)
Paramétré avec le type de résultat et un objet en attachement (contexte qui peut être null)
interface CompletionHandler<V, A> {
void completed(V result, A attachment);
void failed(Throwable t, A attachment);
}
completed() invoqué en cas de succès
failed() invoqué en cas d’erreur
75
Exemple : dupliquer un ficher de manière asynchrone
public static void copierAsync(final AsynchronousFileChannel in,
final AsynchronousFileChannel out) {
final ByteBuffer buffer = ByteBuffer.allocate(16384);
class ReadCompletionHandler implements CompletionHandler<Integer, Integer> {
@Override
public void completed(Integer result, Integer position) {
if (result == -1) {
System.out.println("copie terminee");
return;
}
buffer.flip();
System.out.println("ecriture buffer");
out.write(buffer, position, position + result,
new CompletionHandler<Integer, Integer>() {
@Override
public void completed(Integer result, Integer newPosition) {
buffer.compact();
System.out.println("Lecture buffer");
in.read(buffer, newPosition, newPosition, ReadCompletionHandler.this);
}
76
Exemple : dupliquer un ficher de manière asynchrone
@Override
public void failed(Throwable exc, Integer attachment) {
System.out.println(exc);
throw new IOError(exc);
}
});
}
@Override
public void failed(Throwable exc, Integer attachment) {
System.out.println(exc);
throw new IOError(exc);
}
}
System.out.println("Lecture buffer");
in.read(buffer, 0, 0, new ReadCompletionHandler());
}
77
Les groupes
Les callbacks CompletionHandler sont invoqués par des threads
AsynchronousChannelGroup qui encapsule un pool de threads
DefaultThreadPool
FixedThreadPool
CachedThreadPool
78
Conclusion
79
Conclusion
NIO 2 apporte de nombreuses fonctionnalités attendues depuis longtemps
Les canaux asynchrones ne sont pas facile à utiliser mais les serveurs d’applications devraient en tirer partie
Téléchargez le JDK 7 et essayez
80
Questions
81
Merci pour votre attention
82
Licence
http://creativecommons.org/licenses/by-nc-nd/3.0/deed.fr