Options d'ouverture des fichiers Java

1. Vue d'ensemble

Dans ce tutoriel, nous allons nous concentrer sur les options d'ouverture standard disponibles pour les fichiers en Java.

Nous explorerons l' énumération StandardOpenOption qui implémente l' interface OpenOption et qui définit ces options ouvertes standard.

2. Le paramètre OpenOption

En Java, nous pouvons travailler avec des fichiers à l'aide de l'API NIO2, qui contient plusieurs méthodes utilitaires. Certaines de ces méthodes utilisent un paramètre OpenOption facultatif qui configure la manière d'ouvrir ou de créer un fichier. De plus, ce paramètre aura une valeur par défaut s'il n'est pas défini, qui peut être différente pour chacune de ces méthodes.

Le type enum StandardOpenOption définit les options standard et implémente l' interface OpenOption .

Voici la liste des options prises en charge que nous pouvons utiliser avec l' énumération StandardOpenOptions :

  • WRITE : ouvre le fichier pour un accès en écriture
  • APPEND : ajoute des données au fichier
  • TRUNCATE_EXISTING : tronque le fichier
  • CREATE_NEW : crée un nouveau fichier et lève une exception si le fichier existe déjà
  • CRÉER : ouvre le fichier s'il existe ou crée un nouveau fichier s'il n'existe pas
  • DELETE_ON_CLOSE : supprime le fichier après la fermeture du flux
  • SPARSE : le fichier nouvellement créé sera clairsemé
  • SYNC : préserve le contenu et les métadonnées du fichier synchronisé
  • DSYNC : ne conserve que le contenu du fichier synchronisé

Dans les sections suivantes, nous verrons des exemples d'utilisation de chacune de ces options.

Pour éviter toute confusion sur le chemin du fichier, prenons un handle sur le répertoire personnel de l'utilisateur, qui sera valide sur tous les systèmes d'exploitation:

private static String HOME = System.getProperty("user.home");

3. Ouverture d'un fichier pour lecture et écriture

Premièrement, si nous voulons créer un nouveau fichier s'il n'existe pas, nous pouvons utiliser l'option CREATE :

@Test public void givenExistingPath_whenCreateNewFile_thenCorrect() throws IOException { assertFalse(Files.exists(Paths.get(HOME, "newfile.txt"))); Files.write(path, DUMMY_TEXT.getBytes(), StandardOpenOption.CREATE); assertTrue(Files.exists(path)); }

Nous pouvons également utiliser l'option CREATE_NEW, qui créera un nouveau fichier s'il n'existe pas. Cependant, il lèvera une exception si le fichier existe déjà.

Deuxièmement, si nous voulons ouvrir le fichier pour lecture, nous pouvons utiliser la méthode newInputStream (Path, OpenOption ...). Cette méthode ouvre le fichier en lecture et renvoie un flux d'entrée:

@Test public void givenExistingPath_whenReadExistingFile_thenCorrect() throws IOException { Path path = Paths.get(HOME, DUMMY_FILE_NAME); try (InputStream in = Files.newInputStream(path); BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { String line; while ((line = reader.readLine()) != null) { assertThat(line, CoreMatchers.containsString(DUMMY_TEXT)); } } } 

Remarquez que nous n'avons pas utilisé l'option READ car elle est utilisée par défaut par la méthode newInputStream .

Troisièmement, nous pouvons créer un fichier, l'ajouter à un fichier ou écrire dans un fichier en utilisant la méthode newOutputStream (Path, OpenOption ...). Cette méthode ouvre ou crée un fichier à écrire et renvoie un OutputStream .

L'API créera un nouveau fichier si nous ne spécifions pas les options ouvertes et que le fichier n'existe pas. Cependant, si le fichier existe, il sera tronqué. Cette option est similaire à l'appel de la méthode avec les options CREATE et TRUNCATE_EXISTING .

Ouvrons un fichier existant et ajoutons quelques données:

@Test public void givenExistingPath_whenWriteToExistingFile_thenCorrect() throws IOException { Path path = Paths.get(HOME, DUMMY_FILE_NAME); try (OutputStream out = Files.newOutputStream(path, StandardOpenOption.APPEND, StandardOpenOption.WRITE)) { out.write(ANOTHER_DUMMY_TEXT.getBytes()); } }

4. Création d'un fichier SPARSE

Nous pouvons dire au système de fichiers que le fichier nouvellement créé doit être fragmenté (fichiers contenant des espaces vides qui ne seront pas écrits sur le disque).

Pour cela, nous devons utiliser l'option SPARSE avec l' option CREATE_NEW . Cependant, cette option sera ignorée si le système de fichiers ne prend pas en charge les fichiers épars .

Créons un fichier fragmenté:

@Test public void givenExistingPath_whenCreateSparseFile_thenCorrect() throws IOException { Path path = Paths.get(HOME, "sparse.txt"); Files.write(path, DUMMY_TEXT.getBytes(), StandardOpenOption.CREATE_NEW, StandardOpenOption.SPARSE); }

5. Maintenir le fichier synchronisé

L' énumération StandardOpenOptions a des options SYNC et DSYNC . Ces options nécessitent que les données soient écrites dans le fichier de manière synchrone dans le stockage. En d'autres termes, ceux-ci garantiront que les données ne seront pas perdues en cas de panne du système .

Ajoutons quelques données à notre fichier et utilisons l'option SYNC :

@Test public void givenExistingPath_whenWriteAndSync_thenCorrect() throws IOException { Path path = Paths.get(HOME, DUMMY_FILE_NAME); Files.write(path, ANOTHER_DUMMY_TEXT.getBytes(), StandardOpenOption.APPEND, StandardOpenOption.WRITE, StandardOpenOption.SYNC); }

La différence entre SYNC et DSYNC est que SYNC stocke le contenu et les métadonnées du fichier de manière synchrone dans le stockage, tandis que DSYNC stocke uniquement le contenu du fichier de manière synchrone dans le stockage.

6. Suppression du fichier après la fermeture du flux

L' énumération StandardOpenOptions offre également une option utile qui nous donne la possibilité de détruire le fichier après la fermeture du flux. Ceci est utile si nous voulons créer un fichier temporaire.

Ajoutons quelques données à notre fichier, et utilisons l'option DELETE_ON_CLOSE :

@Test public void givenExistingPath_whenDeleteOnClose_thenCorrect() throws IOException { Path path = Paths.get(HOME, EXISTING_FILE_NAME); assertTrue(Files.exists(path)); // file was already created and exists try (OutputStream out = Files.newOutputStream(path, StandardOpenOption.APPEND, StandardOpenOption.WRITE, StandardOpenOption.DELETE_ON_CLOSE)) { out.write(ANOTHER_DUMMY_TEXT.getBytes()); } assertFalse(Files.exists(path)); // file is deleted }

7. Conclusion

Dans ce didacticiel, nous avons abordé les options disponibles pour ouvrir des fichiers en Java à l'aide de la nouvelle API de système de fichiers (NIO2) fournie avec Java 7.

Comme d'habitude, le code source avec tous les exemples du tutoriel peut être trouvé sur Github.