Bonjour,

Petite revue de code, autrement dit critiques constructives demandées pour le code ci-dessous :

L'idée étant simplement de pouvoir lire le contenu d'un fichier texte (encodé en UTF-8) et d'afficher le contenu sur la sortie console avec le numéro de chaque ligne.

Version alpha
Initialement, j'avais envisagé qqch comme :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
FileReader fr = new FileReader(FICHIER_NOM);
BufferedReader br = new BufferedReader(fr);
LineNumberReader lnr = new LineNumberReader(br);
String ligne = null;
while( null != ( ligne = lnr.readLine() ) )
{
    System.out.println( lnr.getLineNumber() + " : " + ligne );
}
Cependant, le constructeur de FileReader utilise toujours l'encodage par défaut du système, qui peut être différent d'un OS à l'autre? De fait, il est préférable de préciser l'encodage, ce qui peut se faire via InputStreamReader. Confirmez-vous ?

Version beta
Un petit programme complet, qui tourne, suivi de quelques questions :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package testjava;
 
import java.io.*;
import java.nio.charset.*;
 
public class Program
{
    private static String FICHIER_NOM;
    private static Charset FICHIER_ENCODAGE;
 
    static
    {
        FICHIER_NOM = "LISEZMOI.TXT";
        FICHIER_ENCODAGE = StandardCharsets.UTF_8;
    }
 
    private static void lireFichier() throws FileNotFoundException, IOException
    {
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        LineNumberReader lnr = null;
        String ligne = null;
 
        try
        {
            fis = new FileInputStream(FICHIER_NOM);
            isr = new InputStreamReader(fis, FICHIER_ENCODAGE);
            br = new BufferedReader(isr);
            lnr = new LineNumberReader(br);
 
            while( null != ( ligne = lnr.readLine() ) )
            {
                System.out.println( lnr.getLineNumber() + " : " + ligne );
            }
        }
        finally
        {
            if( lnr != null ) lnr.close(); // Est-ce utile ?
            else if( br != null ) br.close();
            else if( isr != null ) isr.close(); 
            else if( fis != null ) fis.close();
        }
    }
 
    public static void main(String[] args) 
    {
        try
        {
            lireFichier();
        }
        catch( Exception ex )
        {
            System.out.println( "Une erreur est survenue : " + ex.toString() );
        }
    }
}
Ouverture et lecture du fichier sont réalisées dans un try{...}finally{...}. Trois questions à ce sujet :
  1. La méthode close() de LineNumberReader est héritée de BufferedReader... de fait, est-il possible (souhaitable?) de n'appeler close() que sur br ? Autrement dit de remplacer "if( lnr != null ) lnr.close(); else if( br != null ) br.close(); else if..." par "if( br != null ) br.close(); else if..." et de ne pas se soucier de réaliser un close() sur lnr ?
  2. Est-il préférable de catcher les erreurs ? Là, je m'en sors facilement via un simple "throws FileNotFoundException, IOException" dans la déclaration de ma fonction lireFichier() : est-ce une bonne pratique ?
  3. Si vous catchez, catchez-vous en imbriquant les try/catch les uns dans les autres ? Catchez-vous également les erreurs possibles sur les closes() dans le catch "final" ?


Version finale
Toutes ces questions sur try/catch m'ont fait penser à l'utilisation de "try-with-resources", et à coder finalement mon petit programme comme suit :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package testjava;
 
import java.io.*;
import java.nio.charset.*;
 
public class Program
{
    private static String FICHIER_NOM;
    private static Charset FICHIER_ENCODAGE;
 
    static
    {
        FICHIER_NOM = "LISEZMOI.TXT";
        FICHIER_ENCODAGE = StandardCharsets.UTF_8;
    }
 
    private static void lireFichier() throws FileNotFoundException, IOException
    {
        String ligne = null;
 
        try
        (
            FileInputStream fis = new FileInputStream(FICHIER_NOM);
            InputStreamReader isr = new InputStreamReader(fis, FICHIER_ENCODAGE);
            BufferedReader br = new BufferedReader(isr);
            LineNumberReader lnr = new LineNumberReader(br);
        )
        {
            while( null != ( ligne = lnr.readLine() ) )
            {
                System.out.println( lnr.getLineNumber() + " : " + ligne );
            }
        }
    }
 
    public static void main(String[] args) 
    {
        try
        {
            lireFichier();
        }
        catch( Exception ex )
        {
            System.out.println( "Une erreur est survenue : " + ex.toString() );
        }
    }
}
Je ne vois plus rien à améliorer, mais peut-être pensez-vous autrement, auquel cas je suis intéressé par vos remarques !

A vos claviers