web-dev-qa-db-fra.com

Fuite de ressources: le 'in' n'est jamais fermé

Pourquoi Eclipse me donne-t-il le message "Fuite de ressources: 'in' n'est jamais fermé" dans le code suivant?

public void readShapeData() {
        Scanner in = new Scanner(System.in);
        System.out.println("Enter the width of the Rectangle: ");
        width = in.nextDouble();
        System.out.println("Enter the height of the Rectangle: ");
        height = in.nextDouble();
74
user1686995

Parce que vous ne fermez pas votre scanner

in.close();
54
nogard

Comme d'autres l'ont déjà dit, vous devez appeler 'close' sur IO classes. J'ajouterai que c'est un excellent endroit pour utiliser l'essai - enfin bloquer sans prise, comme ceci:

public void readShapeData() throws IOException {
    Scanner in = new Scanner(System.in);
    try {
        System.out.println("Enter the width of the Rectangle: ");
        width = in.nextDouble();
        System.out.println("Enter the height of the Rectangle: ");
        height = in.nextDouble();
    } finally {
        in.close();
    }
}

Cela garantit que votre scanner est toujours fermé, garantissant ainsi un nettoyage correct des ressources.

De manière équivalente, dans Java 7 ou supérieur, vous pouvez utiliser la syntaxe "try-with-resources":

try (Scanner in = new Scanner(System.in)) {
    ... 
}
44
Eric Lindauer

Vous devez appeler in.close(), dans un bloc finally, pour vous en assurer.

Dans la documentation Eclipse, voici pourquoi il signale ce problème particulier ( emphase mienne):

Classes implémentant l'interface Java.io.Closeable (depuis JDK 1.5) et Java.lang.AutoCloseable (depuis JDK 1.7) sont considérés comme représentant des ressources externes, qui doivent être fermées à l'aide de la méthode close (), lorsqu'elles ne sont plus nécessaires.

Le compilateur Eclipse Java est capable d'analyser si le code utilisant de tels types adhère à cette stratégie.

...

Le compilateur signalera [violations] avec "La fuite de ressources: le flux n'est jamais fermé".

Explication complète ici .

8
Will

Cela vous indique que vous devez fermer le scanner que vous avez instancié sur System.in avec Scanner.close(). Normalement, chaque lecteur doit être fermé.

Notez que si vous fermez System.in, vous ne pourrez plus le lire. Vous pouvez également consulter la classe Console .

public void readShapeData() {
    Console console = System.console();
    double width = Double.parseDouble(console.readLine("Enter the width of the Rectangle: "));
    double height = Double.parseDouble(console.readLine("Enter the height of the Rectangle: "));
    ...
}
6
Alex

Si vous utilisez JDK7 ou 8, vous pouvez utiliser try-catch avec des ressources. Ceci fermera automatiquement le scanner.

try ( Scanner scanner = new Scanner(System.in); )
  {
    System.out.println("Enter the width of the Rectangle: ");
    width = scanner.nextDouble();
    System.out.println("Enter the height of the Rectangle: ");
    height = scanner.nextDouble();
  }
catch(Exception ex)
{
    //exception handling...do something (e.g., print the error message)
    ex.printStackTrace();
}
4
agyeya

Vous devriez fermer votre scanner lorsque vous avez terminé:

in.close();
3
Dan W

l'ajout de private static Scanner in; ne résout pas vraiment le problème, il efface simplement l'avertissement. Rendre le scanner statique signifie qu'il reste ouvert pour toujours (ou jusqu'à ce que la classe soit déchargée, ce qui est presque "pour toujours"). Le compilateur ne vous avertit plus, puisque vous lui avez dit "gardez-le ouvert pour toujours". Mais ce n’est pas ce que vous vouliez vraiment, car vous devez fermer les ressources dès que vous n’en avez plus besoin.

HTH, Manfred.

2
user2393042

Généralement, les instances de classes traitant d'E/S doivent être fermées une fois que vous avez fini de les utiliser. Donc, à la fin de votre code, vous pouvez ajouter in.close().

2
arshajii
// An InputStream which is typically connected to keyboard input of console programs

Scanner in= new Scanner(System.in);

la ligne ci-dessus invoquera la classe Constructor of Scanner avec l'argument System.in et renverra une référence à un objet nouvellement construit.

Il est connecté à un flux d'entrée connecté au clavier. Vous pouvez donc, au moment de l'exécution, saisir les entrées de l'utilisateur pour effectuer les opérations requises.

//Write piece of code 

Pour supprimer la fuite de mémoire -

in.close();//write at end of code.
2
Aashi
private static Scanner in;

Je l'ai corrigé en déclarant en tant que variable de classe Scanner statique privée. Je ne sais pas pourquoi cela a résolu le problème, mais c'est ce que Eclipse m'a recommandé de faire.

2
zachdyer

Le scanner devrait être fermé. Il est recommandé de fermer les lecteurs, les flux ... et ce type d’objets pour libérer des ressources et éviter les fuites de mémoire. et le faire ensuite dans un bloc pour s’assurer qu’ils sont fermés même si une exception se produit lors de la manipulation de ces objets.

1
Carlos Cambón
Scanner sc = new Scanner(System.in);

//do stuff with sc

sc.close();//write at end of code.
0
tejas