73
1

"Input/Ouput, 16 ans après" à Devoxx France 2012

Embed Size (px)

DESCRIPTION

Ma présentation "Input/Ouput, 16 ans après" a Devoxx France 2012

Citation preview

Page 1: "Input/Ouput, 16 ans après" à Devoxx France 2012

1

Page 2: "Input/Ouput, 16 ans après" à Devoxx France 2012

Abstract

• Revue rapide des I/O avec Java

• Vue d’ensemble de l’API NIO2

• Fournie avec Java SE 7

• Pour les développeurs que nous sommes

2

Page 3: "Input/Ouput, 16 ans après" à Devoxx France 2012

Speaker

http://www.jmdoudoux.fr

@jmdoudoux

Auteur de 2 didacticiels

sous licence GNU FDL

Développons en Java (2400 pages)

Développons en Java avec Eclipse (600 pages)

Membre du et du CA du

3

Page 4: "Input/Ouput, 16 ans après" à Devoxx France 2012

Agenda

• Les entrées / sorties avec Java

• NIO 2

• L’API Filesystem

• Lectures / écritures : API mises à jour

• Les E/S asynchrones (Asynchronous I/O)

4

Page 5: "Input/Ouput, 16 ans après" à Devoxx France 2012

5

Les entrées / sorties avec Java

Page 6: "Input/Ouput, 16 ans après" à Devoxx France 2012

L’API java.io

• Depuis Java 1.0

• Flux : octets (Input/OutputStream)

caractères (Reader/Writer)

• Fichiers, In Memory, Pipes, Sérialisation, …

• Filtre, Buffer, … (adaptateur, décorateur)

• La classe File

6

Page 7: "Input/Ouput, 16 ans après" à Devoxx France 2012

7

Java 1.1 getCanonicalPath()

Java 1.2 getParentFile(), getAbsoluteFile(), getCanonicalFile(),

toURL(), isHidden(), createNewFile(), deleteOnExit(),

listFiles(), setLastModified(), setReadOnly(), listRoots(),

createTempFile(), compareTo()

Java 1.4 création à partir d’une URI, toURI()

Java 6 setWritable(), setReadable(), setExecutable(), canExecute(),

getTotalSpace(), getFreeSpace(), getUsableSpace()

Les évolutions de la classe File

Page 8: "Input/Ouput, 16 ans après" à Devoxx France 2012

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

• …

8

Page 9: "Input/Ouput, 16 ans après" à Devoxx France 2012

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

• …

9

Page 10: "Input/Ouput, 16 ans après" à Devoxx France 2012

New IO (NIO)

• Java 1.4

• utilisation de blocs et non de flux

• les canaux et sélecteurs (channels et selectors),

• les tampons (buffers),

• encodage et décodage de caractères (charset)

10

Page 11: "Input/Ouput, 16 ans après" à Devoxx France 2012

11

NIO 2

Page 12: "Input/Ouput, 16 ans après" à Devoxx France 2012

NIO 2

Inclus dans Java SE 7

JSR 203 : ajout de fonctionnalités à l’API NIO

• Accès et manipulation du système de fichiers

• Mise à jour de l’API existante

• Canaux asynchrones (asynchronous channels)

• …

12

Page 13: "Input/Ouput, 16 ans après" à Devoxx France 2012

L’API FileSystem

• API moderne et complète

• Accès et gestion des systèmes de fichiers (fichiers,

répertoires, liens symboliques, …)

• Support des méta-datas

• Parcours des répertoires, notifications

• Extensible

13

Page 14: "Input/Ouput, 16 ans après" à Devoxx France 2012

L’API FileSystem

14

Page 15: "Input/Ouput, 16 ans après" à Devoxx France 2012

15

Les chemins

Page 16: "Input/Ouput, 16 ans après" à Devoxx France 2012

L’interface Path

• Immuable, encapsule tout ou partie du chemin d’un élément

du système de fichiers

• Dépendant du système de fichier

• Chemin encapsulé absolu ou relatif existe ou non

• Pas de gestion des extensions des fichiers

16

Page 17: "Input/Ouput, 16 ans après" à Devoxx France 2012

Obtenir une instance de type Path

17

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.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");

// Sur Unix

// Path path = Paths.get("/home/jm/temp/monfichier.txt");

Page 18: "Input/Ouput, 16 ans après" à Devoxx France 2012

Path : gérer les éléments

Méthodes pour gérer les éléments hiérarchiques du chemin

18

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

Page 19: "Input/Ouput, 16 ans après" à Devoxx France 2012

Path : gérer les éléments

19

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

Page 20: "Input/Ouput, 16 ans après" à Devoxx France 2012

Path : manipuler le chemin

• 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 fourni

20

Page 21: "Input/Ouput, 16 ans après" à Devoxx France 2012

Manipuler un Path

21

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

Page 22: "Input/Ouput, 16 ans après" à Devoxx France 2012

Path : comparer des chemins

Plusieurs méthodes pour comparer les chemins

• int compareTo(Path other)

• boolean endsWith(Path other)

boolean endsWith(String other)

• boolean startsWith(Path other)

boolean startsWith(String other)

• …

22

Page 23: "Input/Ouput, 16 ans après" à Devoxx France 2012

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 avec résolution des liens

symboliques selon les options fournies

23

Page 24: "Input/Ouput, 16 ans après" à Devoxx France 2012

Path : intégration dans l’existant

• Path File.toPath()

• File Path.toFile()

• URI Path.toUri() : retourner le chemin sous la forme d’une

URI

24

Page 25: "Input/Ouput, 16 ans après" à Devoxx France 2012

25

La manipulation des fichiers

et des répertoires

Page 26: "Input/Ouput, 16 ans après" à Devoxx France 2012

Glob

• Pattern à appliquer sur un élément du système de fichiers

• Sous ensemble des expressions régulières :

* ** ? [] {} \

Exemples :

26

*.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

Page 27: "Input/Ouput, 16 ans après" à Devoxx France 2012

Glob

27

final Path file1 = Paths.get("C:/java/test/test.java");

final Path file2 = Paths.get("C:/java/test/test.txt");

final Path file3 = file1.getFileName();

String pattern = "glob:**/*.{java,class}";

System.out.println("Pattern " + pattern);

PathMatcher matcher = FileSystems.getDefault().getPathMatcher(pattern);

System.out.println(file1 + " " + matcher.matches(file1));

System.out.format("%-22s %b\n", file2, matcher.matches(file2));

System.out.format("%-22s %b\n", file3, matcher.matches(file3));

System.out.println("");

pattern = "glob:*.java";

System.out.println("Pattern " + pattern);

matcher = FileSystems.getDefault().getPathMatcher(pattern);

System.out.println(file1 + " " + matcher.matches(file1));

System.out.format("%-22s %b\n", file3, matcher.matches(file3));

Page 28: "Input/Ouput, 16 ans après" à Devoxx France 2012

La classe Files

• Création : createDirectory(), createFile(), createLink(),

createSymbolicLink(), createTempFile(), createTempDirectory(), …

• Manipulation : delete(), move(), copy(), …

• Type d’un élément : isRegularFile(), isDirectory(),

probeContentType(), …

• Méta-données et permissions : getAttributes(),

getPosixFilePermissions(), isReadable(), isWriteable(), size(),

getFileAttributeView(), …

28

Page 29: "Input/Ouput, 16 ans après" à Devoxx France 2012

Copier un fichier

29

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

}

Copie d’un répertoire

Page 30: "Input/Ouput, 16 ans après" à Devoxx France 2012

Déplacer ou renommer un fichier

30

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

}

Déplacement d’un répertoire

Page 31: "Input/Ouput, 16 ans après" à Devoxx France 2012

Supprimer un fichier

31

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

}

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

}

Suppression d’un répertoire vide

Page 32: "Input/Ouput, 16 ans après" à Devoxx France 2012

Les liens symboliques

• Support optionnel selon le FS (Unix)

• Suivis par défaut avec quelques exceptions :

delete(), move(), walkFileTree()

• Files.isSameFile()

• Files.isSymbolicLink()

• Files.readSymbolicLink()

32

Page 33: "Input/Ouput, 16 ans après" à Devoxx France 2012

Créer un lien / un lien symbolique

33

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

}

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

}

Page 34: "Input/Ouput, 16 ans après" à Devoxx France 2012

34

Les événements sur un répertoire

Page 35: "Input/Ouput, 16 ans après" à Devoxx France 2012

L’interface WatchService

• Notifications de changements dans un répertoire

• Abonnement à des événements lors de la création,

modification, suppression de fichiers

• Evite d’avoir à écrire du code de type pooling ou une API

open source (JNotify ou JPathWatch)

• Non récursif, performant

35

Page 36: "Input/Ouput, 16 ans après" à Devoxx France 2012

L’utilisation de WatchService

Mise en œuvre particulière :

• Instanciation avec FileSystem.newWatchService()

• Enregistrement avec Path.register()

(Path implémente Watchable)

• Obtenir et traiter les événements

36

Page 37: "Input/Ouput, 16 ans après" à Devoxx France 2012

WatchService

37

WatchService watcher = FileSystems.getDefault().newWatchService();

Path dir = Paths.get("c:/java/test");

WatchKey key = dir.register(watcher, ENTRY_CREATE)

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

}

Page 38: "Input/Ouput, 16 ans après" à Devoxx France 2012

38

Les méta-données

Page 39: "Input/Ouput, 16 ans après" à Devoxx France 2012

Les attributs

• Gestion complète des attributs qui sont dépendants du

système sous jacent

• Taille, type d’éléments, caché, …

• Attributs communs (BasicFileAttributes) et spécifiques

(DosFileAttributes, PosixFileAttributes)

• Méthodes de la classe Files

39

Page 40: "Input/Ouput, 16 ans après" à Devoxx France 2012

Les attributs DOS

40

Path fichier = Paths.get("c:/java/test/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());

Page 41: "Input/Ouput, 16 ans après" à Devoxx France 2012

Les attributs Posix

• Énumération PosixFilePermission

• PosixFilePermissions : helper

• FileAttribute : encapsule les attributs

41

Attention aux restrictions de droits via umask

ou via le répertoire parent

Page 42: "Input/Ouput, 16 ans après" à Devoxx France 2012

Les attributs Posix

42

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

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

Page 43: "Input/Ouput, 16 ans après" à Devoxx France 2012

Les attributs avec les vues

• Les vues permettent d’obtenir les attributs d’un même

groupe en bloc -> performance

• Les vues sont spécialisées

• Readonly ou mutable

• Création possible de vues personnalisées

43

Page 44: "Input/Ouput, 16 ans après" à Devoxx France 2012

Les différentes vues

AttributeView

FileAttributeView

BasicFileAttributeView

DosFileAttributeView

PosixFileAttributeView

FileOwnerAttributeView

AclFileAttributeView

PosixFileAttributeView

UserDefinedFileAttributeView

FileStoreAttributeView

44

Page 45: "Input/Ouput, 16 ans après" à Devoxx France 2012

BasicFileAttributView

45

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

Page 46: "Input/Ouput, 16 ans après" à Devoxx France 2012

La classe FileStore

• Encapsule un système de stockage : un disque dur, une

partition, …

• Obtenir des informations

• Connaître les AttributViews supportées

• FileStore Files.getFileStore(Path)

46

Page 47: "Input/Ouput, 16 ans après" à Devoxx France 2012

FileStore

47

for (final FileStore store : FileSystems.getDefault().getFileStores()) {

System.out.println(store);

System.out.println("nom : " + store.name() + ", type : " + fileStore.type());

System.out.println("Support BasicFileAttribute : "

+ store.supportsFileAttributeView(BasicFileAttributeView.class));

System.out.println("Support DosFileAttribute : "

+ store.supportsFileAttributeView(DosFileAttributeView.class));

System.out.println("Support PosixFileAttribute : "

+ store.supportsFileAttributeView(PosixFileAttributeView.class));

}

final int UN_GIGA = 1024 * 1024 * 1024;

for (final FileStore store : FileSystems.getDefault().getFileStores()) {

try {

final long total = store.getTotalSpace() / UN_GIGA;

final long used = (store.getTotalSpace() - store.getUnallocatedSpace())

/ UN_GIGA;

final long avail = store.getUsableSpace() / UN_GIGA;

System.out.format("%-20s total=%5dGo used=%5dGo avail=%5dGo%n",

store, total, used, avail);

} catch (final IOException e) {

e.printStackTrace();

}

}

Page 48: "Input/Ouput, 16 ans après" à Devoxx France 2012

La classe FileSystem

• Encapsule un système de fichiers

• Fabrique pour des objets de l’API

• Obtenir l’instance du système par défaut

FileSystem fs = FilesSystems.getDefault();

48

Page 49: "Input/Ouput, 16 ans après" à Devoxx France 2012

La classe FileSystem

• Extensible

• Peut permettre d’offrir différentes vues d’un système de

fichiers

(cacher des fichiers sensibles, accès en lecture seule, …)

• N’a pas besoin d’être lié à un « vrai » système de fichiers

49

Page 50: "Input/Ouput, 16 ans après" à Devoxx France 2012

Les providers de FileSystem

• Invoquer une fabrique (FileSystems) pour obtenir une

implémentation spécifique

• Utiliser ou de créer des fournisseurs de FileSystem

class MonFileSystem extends FileSystem;

• java.nio.file.spi.FileSystemProvider

50

Page 51: "Input/Ouput, 16 ans après" à Devoxx France 2012

Un provider pour les zip

• Permet de traiter le contenu d’un zip comme un système de

fichiers

• Facilite l’utilisation des archives de type zip

• Fourni en standard

51

Page 52: "Input/Ouput, 16 ans après" à Devoxx France 2012

Afficher un fichier d’un zip

52

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

}

}

Page 53: "Input/Ouput, 16 ans après" à Devoxx France 2012

Extraire et ajouter un fichier à un zip

53

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

Page 54: "Input/Ouput, 16 ans après" à Devoxx France 2012

54

Parcourir le contenu d’un répertoire

DirectoryStream et WalkFileTree

Page 55: "Input/Ouput, 16 ans après" à Devoxx France 2012

L’interface DirectoryStream

• Itération sur le contenu d’un répertoire

• Performance sur de gros répertoires, consomme moins de

ressources

• Possibilité d’appliquer un filtre avec un glob

• Invoquer la méthode close() après utilisation

55

Page 56: "Input/Ouput, 16 ans après" à Devoxx France 2012

DirectoryStream

56

Path dir = Paths.get("C:/java/projets");

try (DirectoryStream<Path> stream =

Files.newDirectoryStream(dir, "*.java")) {

for (Path entry : stream) {

System.out.println(entry.getFileName());

}

}

Page 57: "Input/Ouput, 16 ans après" à Devoxx France 2012

WalkFileTree avec FileVisitor

• Parcourir une arborescence en utilisant le design pattern

Visiteur (opérations récursives)

• Files.walkFileTree()

• FileVisitor invoqué

sur chaque fichier (visitFile() / visitFileFailed())

sur chaque répertoire (preVisitDirectory()/postVisitDirectory())

57

Page 58: "Input/Ouput, 16 ans après" à Devoxx France 2012

WalkFileTree avec FileVisitor

• SimpleFileVisitor : contrôle du parcours par la valeur de

retour (CONTINUE, SKIP_SUBTREE, TERMINATE, …)

• Liens symboliques non suivis par défaut

(FileVisitOption.FOLLOW_LINKS)

• détection des références circulaires (méthode

visitFileFailed() avec FileSystemLoopException)

58

Page 59: "Input/Ouput, 16 ans après" à Devoxx France 2012

WalkFileTree

59

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;

}

});

Page 60: "Input/Ouput, 16 ans après" à Devoxx France 2012

60

Lectures / écritures

Mises à jour de l’API

Page 61: "Input/Ouput, 16 ans après" à Devoxx France 2012

Gestion des IO avec Java

61

IO

Java 1.0

Synchrone

Bloquant

File InputStream OutputStream Reader Writer Socket RandomAccessFile

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 SeekableByteChannel

Page 62: "Input/Ouput, 16 ans après" à Devoxx France 2012

Les méthodes de la classe Files

62

Besoins

avancés

Besoins

simples

Page 63: "Input/Ouput, 16 ans après" à Devoxx France 2012

Lire et écrire tout le contenu d’un fichier

63

byte[] bytes = Files.readAllBytes(path);

List<String> lignes = Files.readAllLines(path,

Charset.defaultCharset());

Files.write(path, bytes);

Files.write(path, lignes, Charset.defaultCharset());

Page 64: "Input/Ouput, 16 ans après" à Devoxx France 2012

Ecrire dans un fichier texte

64

final Path fichier =

Paths.get("c:/java/test/donnees.txt");

final Charset charset = Charset.forName("UTF8");

final String contenu = "Prix 10€";

Files.deleteIfExists(fichier);

try (BufferedWriter writer =

Files.newBufferedWriter(fichier, charset)) {

writer.write(contenu, 0, contenu.length());

} catch (IOException ioe) {

// traitement de l'erreur

}

}

Page 65: "Input/Ouput, 16 ans après" à Devoxx France 2012

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, …

65

Page 66: "Input/Ouput, 16 ans après" à Devoxx France 2012

SeekableByteChannel

66

ByteBuffer donneesBonjour =

ByteBuffer.wrap("Bonjour".getBytes());

ByteBuffer donneesBonsoir =

ByteBuffer.wrap("Bonsoir".getBytes());

Path path = Paths.get("C:/java/test/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);

}

Page 67: "Input/Ouput, 16 ans après" à Devoxx France 2012

67

Lectures / écritures

asynchrones

Page 68: "Input/Ouput, 16 ans après" à Devoxx France 2012

Les canaux asynchrones

• Channel : opérations non bloquantes (lecture, écriture)

• AsynchronousChannel : opérations asynchrones (exécutées

dans un thread)

• Contrôle des opérations après leur initialisation via deux

solutions :

java.util.concurrent.Future

java.nio.channels.CompletionHandler

68

Page 69: "Input/Ouput, 16 ans après" à Devoxx France 2012

Canaux async 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)

69

interface CompletionHandler<V, A> {

void completed(V result, A attachment);

void failed(Throwable t, A attachment);

}

Page 70: "Input/Ouput, 16 ans après" à Devoxx France 2012

Canaux async : les groupes

• Les CompletionHandler sont invoqués par les threads

• AsynchronousChannelGroup encapsule un pool de threads

• FixedThreadPool

• CachedThreadPool

70

Page 71: "Input/Ouput, 16 ans après" à Devoxx France 2012

71

Conclusion

Page 72: "Input/Ouput, 16 ans après" à Devoxx France 2012

Conclusion

• NIO2 apporte de nombreuses fonctionnalités, attendues

depuis longtemps

• Implémentation de bas niveau de certaines, mais utilisables

dans différents contextes

• Pour allez plus loin : Javadoc, Java tutorials (Basic I/O),

exemples du JDK (sample/nio/file)

72

Page 73: "Input/Ouput, 16 ans après" à Devoxx France 2012

73