• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
NIO 2
 

NIO 2

on

  • 1,906 views

 

Statistics

Views

Total Views
1,906
Views on SlideShare
1,431
Embed Views
475

Actions

Likes
0
Downloads
24
Comments
0

10 Embeds 475

http://lorrainejug.blogspot.com 347
http://lorrainejug.github.io 36
http://lorrainejug.blogspot.fr 34
http://localhost 27
http://0.0.0.0 14
http://www.yatedo.fr 7
http://lorrainejug.blogspot.be 5
http://a0.twimg.com 2
http://www.yatedo.com 2
http://lorrainejug.blogspot.co.uk 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    NIO 2 NIO 2 Presentation Transcript

    • Qui suis-je ?  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 2
    • Plan NIO2 FileSystem API Lectures/écritures : API mises à jour Canaux asynchrones (Asynchronous I/0) Conclusion 3
    • NIO 2 4
    • Les défauts de java.io  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  … 5
    • Les défauts de la classe File  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 6
    • Spécification JSR 203 JSR 203 : http://www.jcp.org/en/jsr/detail?id=203 7
    • NIO 2JSR 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 8
    • FileSystem API 9
    • 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) 10
    • L’API FileSystem 11
    • 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 12
    • L’interface Path 13
    • 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 14
    • L’interface Path  Création à partir d’un String, URI ou java.io.File  La classe helper PathsPaths.get("monfichier.txt");Paths.get("jm/AppData/Local/Temp/monfichier.txt");Paths.get("C:/Users/jm/AppData/Local/Temp/monfichier.txt");Paths.get("C:UsersjmAppDataLocalTempmonfichier.txt");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"); 15
    • 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 16
    • L’interface Path : exempletoString() = C:UsersjmAppDataLocalTempmonfichier.txtgetFileName() = monfichier.txtgetRoot() = C:getName(0) = UsersgetNameCount() = 6getParent() = C:UsersjmAppDataLocalTempsubpath(0,3) = UsersjmAppDatatoString() = jmAppDataLocalTempmonfichier.txtgetFileName() = monfichier.txtgetRoot() = nullgetName(0) = jmgetNameCount() = 5getParent() = jmAppDataLocalTempsubpath(0,3) = jmAppDataLocal 17
    • 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 18
    • L’interface Path : manipuler des cheminspath = Paths.get("C:/Users/admin/./../jm/AppData/Local/Temp/./monfichier.txt");System.out.println("normalize() = " + path.normalize());normalize() = C:USersjmAppDataLocalTempmonfichier.txtPath 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:UsersjmAppDataLocalTempmonfichier.txtC:Temp 19
    • 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 20
    • 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é 21
    • 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 22
    • 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 23
    • 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); 24
    • La manipulation des fichiers et des répertoires 25
    • 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(), … 26
    • 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 } 27
    • 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 } 28
    • 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 } 29
    • 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 } 30
    • Les liens symboliques 31
    • 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() 32
    • 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"); } 33
    • 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"); } 34
    • L’interface WatchService 35
    • 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 36
    • 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) 37
    • 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(); } 38
    • Les méta-données 39
    • 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 40
    • 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()); 41
    • 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); 42
    • 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); 43
    • Les attributs via les vues  Les vues permettent d’obtenir les attributs en bloc  Les vues sont spécialisées  Readonly ou mutable 44
    • Les attributs via les vues AttributeView FileAttributeView BasicFileAttributeView DosFileAttributeView PosixFileAttributeView FileOwnerAttributeView AclFileAttributeView PosixFileAttributeView UserDefinedFileAttributeView FileStoreAttributeView 45
    • Exemple avec BasicFileAttributViewPath 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(); 46
    • La classe FileStore 47
    • La classe FileStore  Encapsule un système de stockage : un disque dur, une partition, …  Obtenir des informations  FileStore Files.getFileStore(Path) 48
    • 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 "); 49
    • La classe FileSystem 50
    • 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(); 51
    • Le séparateur du système de fichiers String separateur = File.separator; String separateur = FileSystems.getDefault().getSeparator(); 52
    • 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 53
    • 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 54
    • 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); } } 55
    • 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 larchive Files.copy(fs.getPath("/META-INF/MANIFEST.MF"), cible); 56
    • L’interface DirectoryStream 57
    • 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 58
    • 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()); } } 59
    • WalkFileTree 60
    • 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 61
    • WalkFileTree : exemplePath 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; }}); 62
    • Lectures / écrituresMises à jour de l’API 63
    • La gestion des io avec Java IO  NIO  NIO 2 Java 1.0  Java 1.4 (JSR 51)  Java 7 (JSR 203) Synchrone  Synchrone  ASynchrone Bloquant  Non bloquant  Non bloquant File  FileChannel  Path InputStream SocketChannel OutputStream ServerSocketChannel  AsynchronousFileChannel Reader (Charset, Selector, AsynchronousByteChannel Writer ByteBuffer) AsynchronousSocketChannel Socket AsynchronousServerSocketC RandomAccessFile hannel 64
    • Obtenir des fluxPath 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); 65
    • L’utilisation des méthodes 66
    • Lire et écrire tout le contenubyte[] bytes = Files.readAllBytes(path);List<String> lignes = Files.readAllLines(path, Charset.defaultCharset());Files.write(path, bytes);Files.write(path, lignes, Charset.defaultCharset()); 67
    • 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 lerreur } 68
    • 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... 69
    • 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); } 70
    • Canaux asynchrones(Asynchronous I/0) 71
    • 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 72
    • 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 73
    • 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 74
    • 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); } 75
    • 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()); } 76
    • Les groupes  Les callbacks CompletionHandler sont invoqués par des threads  AsynchronousChannelGroup qui encapsule un pool de threads  DefaultThreadPool  FixedThreadPool  CachedThreadPool 77
    • Conclusion 78
    • 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 79
    • Questions 80
    • Merci pour votre attention 81
    • Licencehttp://creativecommons.org/licenses/by-nc-nd/3.0/deed.fr 82