Les FAQs Java :
FAQ JAVA FAQ Java EE FAQ Java ME FAQ Java XML FAQ JavaFX FAQ Java GUI FAQ Struts FAQ JSF FAQ JDBC JDO FAQ Hibernate FAQ Spring FAQ Eclipse FAQ NetBeans FAQ JCreator FAQ Maven 2

FAQ JavaConsultez toutes les FAQ

Nombre d'auteurs : 53, nombre de questions : 231, dernière mise à jour : 26 janvier 2014 

 
OuvrirSommaireFichiers, flux et réseauxFlux et fichiers

La classe java.io.File fournit la méthode statique listRoots(). Sous Windows, le résultat est la liste des lecteurs logiques ( a:/, c:/, d:/ ), sous Unix, le résultat se limite à la seule racine système.

 
Sélectionnez
File[] listeRacine = File.listRoots();
Mis à jour le 6 mai 2002  par Clément Cunin

Pour obtenir la liste des fichiers d'un répertoire :

 
Sélectionnez

/** Class : java.io.File */
public File [] listFiles ();

Pour connaître le type d'un fichier :

 
Sélectionnez

/** Class : java.io.File */
public boolean isDirectory ();
public boolean isFile ();

Exemple :
Cet exemple effectue un parcours récursif d'une arborescence de fichiers et affiche (sur la sortie standard) la liste de tous les fichiers contenus dans le répertoire et ses sous-répertoires.

 
Sélectionnez

public static void listeRepertoire ( File repertoire ) {
        System.out.println ( repertoire.getAbsolutePath());
 
        if ( repertoire.isDirectory ( ) ) {
                File[] list = repertoire.listFiles();
                if (list != null){
	                for ( int i = 0; i < list.length; i++) {
	                        // Appel récursif sur les sous-répertoires
	                        listeRepertoire( list[i]);
	                } 
                } else {
                	System.err.println(repertoire + " : Erreur de lecture.");
                }
        } 
} 

Attention : cet algorithme ne fonctionne pas correctement avec une arborescence cyclique sous Unix !

Mis à jour le 1er mars 2003  par Clément Cunin

Lien : Comment connaître les racines des arborescences de fichiers ?
Lien : Comment indiquer la position d'un fichier en conservant la portabilité ?

Copie de fichier :
L'Api ne fournissant pas de solution clé en main pour la copie de fichier, voila un bout de code qui devrait fonctionner.

 
Sélectionnez

/** copie le fichier source dans le fichier resultat
 * retourne vrai si cela réussit
 */
public static boolean copyFile(File source, File dest){
	try{
		// Declaration et ouverture des flux
		java.io.FileInputStream sourceFile = new java.io.FileInputStream(source);
 
		try{
			java.io.FileOutputStream destinationFile = null;
 
			try{
				destinationFile = new FileOutputStream(dest);
 
				// Lecture par segment de 0.5Mo 
				byte buffer[] = new byte[512 * 1024];
				int nbLecture;
 
				while ((nbLecture = sourceFile.read(buffer)) != -1){
					destinationFile.write(buffer, 0, nbLecture);
				}
			} finally {
				destinationFile.close();
			}
		} finally {
			sourceFile.close();
		}
	} catch (IOException e){
		e.printStackTrace();
		return false; // Erreur
	}
 
	return true; // Résultat OK  
}

Depuis Java 1.4, l'Api de Java a été enrichie de nio. Voici le code à utiliser pour une copie plus rapide de fichier en utilisant nio :

 
Sélectionnez

FileChannel in = null; // canal d'entrée
FileChannel out = null; // canal de sortie
 
try {
  // Init
  in = new FileInputStream("toto.txt").getChannel();
  out = new FileOutputStream("tutu.txt").getChannel();
 
  // Copie depuis le in vers le out
  in.transferTo(0, in.size(), out);
} catch (Exception e) {
  e.printStackTrace(); // n'importe quelle exception
} finally { // finalement on ferme
  if(in != null) {
  	try {
	  in.close();
	} catch (IOException e) {}
  }
  if(out != null) {
  	try {
	  out.close();
	} catch (IOException e) {}
  }
}

Déplacer un fichier
On n'a vu que le déplacement d'un fichier pouvait être fait grâce à la méthode renameTo(java.io.File) de la classe java.io.File ( voir ici ) Mais cette solution n'est valable que pour des déplacements à l'intérieur d'un disque physique...
On va donc utilisé l'algorithme de copie lorsque le renommage ne suffit pas :

 
Sélectionnez

public static boolean deplacer(File source,File destination) {
        if( !destination.exists() ) {
                // On essaye avec renameTo
                boolean result = source.renameTo(destination);
                if( !result ) {
                        // On essaye de copier
                        result = true;
                        result &= copier(source,destination);
                        if(result) result &= source.delete();
 
                } return(result);
        } else {
                // Si le fichier destination existe, on annule ...
                return(false);
        } 
} 
Mis à jour le 7 juin 2009  par Clément Cunin

Supprimer un fichier ou un répertoire vide :
La suppression des fichiers et des répertoires vides est effectuée grâce à la méthode delete() de la classe java.io.File. Un booléen en résultat indique si la suppression a réussi (cause d'échec : Fichier inexistant; Fichier en lecture seule; Le fichier est ouvert par une application ou par le système; Flux ouvert sur le fichier; etc...).

Supprimer un répertoire non-vide :
L'Api de base ne permet pas de supprimer un répertoire contenant des fichiers, il faut donc supprimer à la main tous les fichiers du répertoire avant !

 
Sélectionnez

static public boolean deleteDirectory(File path) { 
        boolean resultat = true; 
 
        if( path.exists() ) { 
                File[] files = path.listFiles(); 
                for(int i=0; i<files.length; i++) { 
                        if(files[i].isDirectory()) { 
                                resultat &= deleteDirectory(files[i]); 
                        } 
                        else { 
                        resultat &= files[i].delete(); 
                        } 
                } 
        } 
        resultat &= path.delete(); 
        return( resultat ); 
} 
Créé le 12 juin 2002  par Clément Cunin

La méthode renameTo(java.io.File) de la classe java.io.File permet très facilement de renommer un fichier. De plus, si le répertoire destination est différent du répertoire source, le fichier sera déplacé. (ATTENTION : le déplacement n'est effectué que si la source et la destination sont sur le même disque physique, sinon une copie de fichier est nécessaire)

 
Sélectionnez

File source = new File("mon fichier");
File destination = new File("mon fichier renommé");
source.renameTo(destination);
Mis à jour le 12 juin 2002  par Clément Cunin

Lien : Comment indiquer la position d'un fichier en conservant la portabilité ?
Lien : Comment copier ou déplacer un fichier ?

Un fichier temporaire est un fichier qui sera créé dans le répertoire temporaire du système et qui sera automatiquement supprimé à la fin de l'application (si la JVM quitte correctement).

 
Sélectionnez

File temp = File.createTempFile("nom",".tmp");
temp.deleteOnExit();
Créé le 10 novembre 2002  par Clément Cunin

Pour écrire à la fin d'un fichier il faut utiliser la classe java.io.FileWriter.
Cette classe possède des constructeurs acceptant parmi leurs arguments un booléen nommé append.
Si cet argument est positionné à true, les données écrites dans ce fichier seront mises à la fin de celui-ci.

Voici un exemple d'utilisation:

 
Sélectionnez

FileWriter writer = null;
String texte = "texte à insérer à la fin du fichier";
try{
     writer = new FileWriter("fichier.txt", true);
     writer.write(texte,0,texte.length());
}catch(IOException ex){
    ex.printStackTrace();
}finally{
  if(writer != null){
     writer.close();
  }
}
Mis à jour le 21 octobre 2007  par bulbo

Lien : http://anisfrikha.developpez.com/tutoriel/java-io/

Cette information peut être accessible grâce à la classe URLConnection du package java.net Par exemple :

 
Sélectionnez

public static String getMIMEType(File file){
   if(file.isDirectory()){return "repertoire";}
   if(!file.exists()){return "fichier inexistant";}
   try{
      URL url = file.toURL();
      URLConnection connection = url.openConnection();
      return connection.getContentType();
   }catch(MalformedURLException mue){
      return mue.getMessage();
   }catch(IOException ioe){
      return ioe.getMessage();
      }
}

Pour plus de "sécurité", vous pouvez utiliser la méthode statique guessContentTypeFromStream. A la différence de getContentType (ou guessContentTypeFromName) cette méthode essaye de déterminer le type MIME en lisant directement les premiers bytes de l'InputStream.

Mis à jour le 12 décembre 2004  par Ioan Calapodescu

Date de création :
Aucune solution n'est disponible pour connaître la date de création d'un fichier. Certains systèmes comme Linux ne fournissant pas cette information, aucun solution portable n'est possible.

Date de la dernière modification :
Là, en revanche, aucun problème, la méthode lastModified() de la classe java.io.File est disponible.

 
Sélectionnez
long dateModification = monFichier.lastModified();

Toutefois, le long retourné par la méthode lastModified() peut dépendre du système d'exploitation et donc ne pas être toujours extrêmement précise.

Mis à jour le 2 juin 2007  par L'équipe Java

En utilisant la classe java.io.File:

 
Sélectionnez

File.length();
Créé le 12 octobre 2006  par bulbo

Aucune solution n'est pleinement portable, donc aucune solution pure Java.

JConfig
est une bibliothèque supplémentaire qui est lié à du code natif disponible pour plusieurs plateformes. Elle permet d'accéder à cette information, ainsi que beaucoup d'autre choses. http://www.tolstoy.com/samizdat/jconfig.html

Dans Java 6, il est désormais possible de connaître simplement l'espace libre, l'espace utilisable et l'espace totale grâce à trois nouvelles méthodes de la classe File.

 
Sélectionnez

public long getTotalSpace();
public long getFreeSpace();
public long getUsableSpace();
Créé le 6 juin 2002  par Clément Cunin

Les différents systèmes d'exploitation ne gèrent pas les arborescences de fichier de la même façon. Le monde Windows associe les périphériques physiques à des lettres de lecteur, le monde Unix utilise un seul répertoire racine. De plus, les séparateurs de fichier ne sont pas les mêmes (respectivement '\' et '/'). Tout ceci doit être analysé afin d'assurer la portabilité de l'application. Heureusement Java fournit tous les outils pour localiser efficacement les fichiers en gardant toute l'indépendance vis à vis du système d'exploitation.

Le plus important est de ne jamais utiliser directement de séparateur de fichier mais d'utiliser la constante définie en fonction du système dans la classe java.io.File.

 
Sélectionnez

/** Class : java.io.File */
public static final char separatorChar;

Si vous désirez exprimer une liste de fichiers, il convient également d'utiliser la constante prévue à cet effet.

 
Sélectionnez

/** Class : java.io.File */
public static final char pathSeparatorChar;
Créé le 22 mars 2002  par Clément Cunin

Lien : Comment parcourir une arborescence de fichiers ?

L'entrée standard est accessible au programmeur grâce au flux 'in' de la classe java.lang.System. Si vous exécutez votre application dans une console, l'entrée standard contiendra tous les caractères entrés au clavier dans la console. La manipulation directe du flux n'étant pas très aisée, une petite conversion en java.io.BufferedReader s'impose.

 
Sélectionnez

/** Convertion du flux en BufferedReader */
BufferedReader entree = new BufferedReader(new InputStreamReader(System.in));
 
try {
        /** Lecture d'une ligne : */entree.readLine();
} catch( IOException e ) {
        e.printStackTrace();
} 

Note : La lecture d'une ligne est une méthode dite 'blocante', tant que l'utilisateur n'a pas fait 'entrée', le processus attends.

Depuis J2SE 5.0 (Tiger) vous pouvez aussi utiliser un Scanner pour parser la sortie standard. Par exemple :

 
Sélectionnez
Scanner scanner = new Scanner(System.in);
// traitement
scanner.close(); 

Le Scanner a l'avantage de possèder un ensemble de méthodes permettant de lire "directement" les types primitifs. Vous pouvez aussi l'utiliser pour faire des recherches dans les flux scannés avec des expressions régulières.

Depuis JAVA SE 6, il est possible de lire sur l'entrée standard via la classe Console.

Par exemple :

 
Sélectionnez
Console console=System.console();
String ligneLue=console.readLine();

La classe Console propose également la méthode printf (si chère aux programmeurs C), ainsi qu'une méthode readPassword() qui n'affiche pas les carctères sur la console.

Mis à jour le 12 janvier 2008  par Clément Cunin

Si pour une raison quelconque, vous avez besoin de récupérer tout ce qui arrive sur la sortir standard dans des fichiers, il suffit d'employer les méthodes setOut et setErr de la classe System :

 
Sélectionnez
System.setOut(new PrintStream(new FileOutputStream("out.log")));
System.setErr(new PrintStream(new FileOutputStream("err.log")));
Mis à jour le 1er mai 2008  par Baptiste Wicht

Pour faire cela, il faut utiliser les méthodes getResource et getResourceAsStream de la classe Class. Le chemin à passer en argument est celui commençant dans le répertoire du CLASSPATH ou a la racine d'un fichier jar. Attention si le chemin ne commence pas par "/" alors le package courant est ajouté au début du chemin. Exemple:

 
Sélectionnez

package com.developpez; 
 
public class Test 
{ 
 
  public Test() 
  { 
    InputStream is1 = getClass().getResourceAsStream("fichier.txt"); 
 
    InputStream is2 = getClass().getResourceAsStream("/fichier.txt"); 
  } 
} 

Dans le code de l'exemple is1 sera un InputStream ouvert sur un fichier "com/developpez/fichier.txt" présent dans un des répertoires du CLASSPATH ou dans la même arborescence à partir de la racine d'un fichier jar du CLASSPATH. is2 sera un InputStream ouvert sur un fichier "fichier.txt" présent directement dans un répertoire du CLASSPATH ou a la racine d'un fichier jar.

Créé le 19 juillet 2004  par bulbo

On peut spécifier l'encodage utilisé pour lire un flux. Voici un exemple qui lis un fichier en UTF-8 et écris celui-ci en ISO-8859-1 :

 
Sélectionnez

   public static void toISO(String source, String destination){
      BufferedReader br = null;
      PrintWriter pw = null;
      try{
         //flux de lecture en UTF-8
         br = new BufferedReader(
               new InputStreamReader(
                     new FileInputStream(source),"UTF-8"));
         //flux d'écriture en ISO (valeur par défaut)
         pw = new PrintWriter(new FileOutputStream(destination));
         String ligne;
         while((ligne = br.readLine())!=null){
            pw.println(ligne);
         }
      }catch(Exception e){e.printStackTrace();}   
      finally{
         try { pw.close(); } catch( Throwable e ) {}
         try { br.close(); } catch( Throwable e ) {} 
      }
   } 
Créé le 9 septembre 2004  par Ioan Calapodescu

Lien : Comment gérer l'encodage d'un tableau de bytes dans des String ?

La classe java.nio.Charset nous permet de facilement accèder à ces informations.

Voici un exemple listant l'ensemble des charsets disponibles :

 
Sélectionnez

SortedMap<String,Charset> charsets = Charset.availableCharsets();
for(String nom : charsets.keySet()){
   System.out.println("Charset "+nom);
   Charset charset = charsets.get(nom);
   for(String alias : charset.aliases()){
      System.out.print(" "+alias+",");
   }
   System.out.println();
}
Créé le 9 septembre 2004  par Ioan Calapodescu

Lien : Comment changer l'encodage d'un fichier texte ?
Lien : Comment gérer l'encodage d'un tableau de bytes dans des String ?

Oui, cela est possible. Ceci peut être utile par exemple pour afficher corectement les caractères accentués.

Voici un exemple permettant d'écrire correctement les caractères accentués sur la console windows (DOS) :

 
Sélectionnez

PrintStream ps = new PrintStream(System.out,true,"IBM850");
// on commence par changer l'encodage en IBM850 (connu aussi sous l'alias Cp850)
System.setOut(ps);
// ensuite l'utilisation de la sortie standard reste la même
System.out.println("àâäÂÄéèêëîïÎÏÊËôöÔÖûüùÛÜÿç"); 
Créé le 9 septembre 2004  par Ioan Calapodescu

Lien : Comment gérer l'encodage d'un tableau de bytes dans des String ?
Lien : Comment changer l'encodage d'un fichier texte ?
Lien : Comment connaître les Charset disponibles et leurs alias ?

La machine virtuelle Java (et plus précisément le Garbage Collector) s'occupe de libérer proprement la mémoire lorsque les objets ne sont plus utilisés.

Toutefois, il existe un certain nombre de ressources qui doivent être libéré explicitement, comme par exemple les fichiers, les sockets ou les connections JDBC, car ils utilisent des ressources systèmes qui ne peuvent pas être gérées par le Garbage Collector...

Ces ressources doivent être "libérées" explicitement grâce à une méthode spécifique (généralement nommé close()).

Or on ne peut pas se contenter d'appeler cette méthode à la fin du traitement, car il y a un certain nombre de cas où cette méthode ne serait pas appelée (par exemple en cas d'exception ou de retour de la méthode).

Il est également fortement déconseillé d'appeler cette méthode aux divers points de sortie du code (fin du traitement, dans les catch, avant les return, etc.), car cela complexifie le code et son traitement, et augmente ainsi les chances de se tromper (en oubliant un cas particulier par exemple).

La solution la plus propre à mettre en oeuvre est d'utiliser un bloc try/finally qui respecte la structure suivante :

 
Sélectionnez
// 1 - Création de la ressource
try {
    // 2 - Utilisation de la ressource
} finally {
    // 3 - Libération de la ressource
}

Ainsi, lorsque la ressource est correctement créé, on l'utilise exclusivement à l'intérieur du try, et on la libère dans le bloc finally quoi qu'il arrive. En effet, si on rentre dans le bloc try, le code du bloc finally sera exécuté dans tous les cas lorsqu'on sort de celui-ci, même si une exception est levée ou que l'on quitte la méthode avec return...

Cette organisation en trois étapes permet donc de garantir la libération propre des ressources dans tous les cas.

Par exemple le code permettant de lire un fichier texte pourrait ressembler à ceci :

 
Sélectionnez

public static String readFile(File file) throws IOException, FileNotFoundException {
    // 1 - Création de la ressource
    FileReader reader = new FileReader(file);
    try {
        // 2 - Utilisation de la ressource
        StringBuffer buffer = new StringBuffer();
        char[] cbuf = new char[2048];
        int len;
        while ( (len = reader.read(cbuf)) > 0 ) {
            buffer.append(cbuf, 0, len);
        }
        return buffer.toString();
    } finally {
        // 3 - Libération de la ressource
        reader.close();
    }
}

Cela permet de faire remonter simplement les exceptions à la méthode appelante tout en fermant correctement la ressource (FileReader).

De la même manière, si l'on souhaite gérer les exceptions dans la méthode, il est préférable d'utiliser un bloc try/catch en plus du bloc try/finally et non pas un bloc try/catch/finally qui nécessiterais un nouveau try/catch dans le bloc finally (et donc un double traitement des exceptions). Par exemple :

 
Sélectionnez

public static String readFile(File file) {
    try {
        // 1 - Création de la ressource
        FileReader reader = new FileReader(file);
        try {
            // 2 - Utilisation de la ressource
            StringBuffer buffer = new StringBuffer();
            char[] cbuf = new char[2048];
            int len;
            while ( (len = reader.read(cbuf)) > 0 ) {
                buffer.append(cbuf, 0, len);
            }
            return buffer.toString();
        } finally {
            // 3 - Libération de la ressource
            reader.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
 
}

Enfin, si l'on utilise plusieurs ressources à la fois, il ne faut pas hésiter à encapsuler plusieurs try/finally (un par ressource). Par exemple dans ce code qui permet de sauvegarder une URL dans un fichier :

 
Sélectionnez

public static void writeToFile(URL url, File file) throws IOException, FileNotFoundException {
    // 1 - Création de la ressource (Fichier)
    FileOutputStream fos = new FileOutputStream(file);
    try {
        // 2 - Utilisation de la ressource (Fichier)
 
        // 1 - Création de la ressource (URL)
        InputStream is = url.openStream();
        try {
            // 2 - Utilisation de la ressource (URL)
            byte[] buf = new byte[2048];
            int len;
            while ( (len = is.read(buf)) > 0) {
                fos.write(buf, 0 , len);
            }
        } finally {
            // 3 - Libération de la ressource (URL)
            is.close();
        }
    } finally {
        // 3 - Libération de la ressource (Fichier)
        fos.close();
    }
}

Si cela peut avoir peu d'importance dans une application de bureau, c'est nettement plus critique dans une application serveur car on peut vite atteindre les limites autorisées par le système, et se retrouver avec une application complètement bloquée !

A noter enfin que le Garbage Collector "limite" quand même ce phénomène, car la méthode close() est généralement appelé implicitement lors de la destruction de l'objet (plus précisément via la méthode finalize()) si la ressource n'a pas été fermé explicitement.

Toutefois, étant donnée que l'on ne peut pas maîtriser le passage du Garbage Collector avec exactitude , il est préférable de fermer les ressources explicitement avec un bloc try/finally.

Créé le 3 février 2007  par adiGuba

Pour lire les éléments d'un fichier en utilisant un délimiteur, il suffit d'avoir recours à la classe java.util.Scanner (arrivée dans le JDK 5.0).

Par exemple pour lire un fichier dont les champs sont séparé par des tabulations, on pourra écrire :

 
Sélectionnez
Reader reader = null;
// initialisation du reader ...
 
Scanner scanner=new Scanner(reader);
 
// L'expression régulière qui délimite les champs
scanner.useDelimiter(Pattern.compile("[\t\n]"));
 
// On boucle sur chaque champ detecté
int champ;
while (scanner.hasNext()) {
    // Si le champ n'est pas un entier, une exception de type InputMismatchException sera levée
    champ = scanner.nextInt();
 
    //Utilisation du champ...
}
Créé le 3 février 2007  par bobuse


Le traitement d'un fichier ligne par ligne est assez simple, mais il faut quand même connaître la manière de s'y prendre. Pour se faire, on va utiliser un simple BufferedReader pour lire le fichier et ensuite utiliser la méthode readLine() pour lire une ligne de notre fichier.


Voilà donc ce que pourrait donner notre code :

 
Sélectionnez
String filePath = "g:\\fichier.txt";
 
try{
// Création du flux bufférisé sur un FileReader, immédiatement suivi par un 
// try/finally, ce qui permet de ne fermer le flux QUE s'il le reader
// est correctement instancié (évite les NullPointerException)
BufferedReader buff = new BufferedReader(new FileReader(filePath));
 
try {
String line;
// Lecture du fichier ligne par ligne. Cette boucle se termine
// quand la méthode retourne la valeur null.
while ((line = buff.readLine()) != null) {
System.out.println(line);
//faites ici votre traitement
}
} finally {
// dans tous les cas, on ferme nos flux
buff.close();
}
} catch (IOException ioe) {
// erreur de fermeture des flux
System.out.println("Erreur --" + ioe.toString());
}


Depuis Java 5.0, On peut également utiliser la classe Scanner pour lire un fichier ligne par ligne :

 
Sélectionnez
String filePath = "g:\\fichier.txt";
 
Scanner scanner=new Scanner(new File(filePath));
 
// On boucle sur chaque champ detecté
while (scanner.hasNextLine()) {
    String line = scanner.nextLine();
 
    System.out.println(line);
	//faites ici votre traitement
}
 
scanner.close();
Mis à jour le 1er mai 2008  par sironimo, Baptiste Wicht

Lien : La classe java.util.Scanner

Les codes sources présentés sur cette page sont libres de droits, et vous pouvez les utiliser à votre convenance. Pour le reste, ce document constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Ce document issu de http://www.developpez.com est soumis à deux licences, en fonction des contributeurs : - Les contributions de Clément Cunin et Johann Heymes sont soumises aux termes de la la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies des contributions de Clément Cunin et Johann Heymes tant que cette note apparaît clairement : "Ce document issu de http://www.developpez.com est soumis à la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies de cette page tant que cette note apparaît clairement". - Pour ce qui est des autres contributions : Copyright © 2014 Developpez LLC : Tous droits réservés Developpez LLC. Aucune reproduction, ne peut en être faite sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.