Domanda

Quando si legge da un file di testo, in genere si crea un FileReader e poi lo nidifica in a BufferedReader. Quale dei due lettori dovrei chiudere quando ho finito di leggere? Importa?

FileReader fr = null;
BufferedReader br = null;
try
{
    fr = new FileReader(fileName);
    br = new BufferedReader(fr);
    // ...
}
finally
{
    // should I close fr or br here?
}

Sono un po 'paranoico quando si tratta di sicurezza delle eccezioni. Cosa succede quando il BufferedReader Il costruttore lancia un'eccezione? Chiude il lettore nidificato? O è garantito non lanciare?

È stato utile?

Soluzione

In genere, close() Sull'involucro di flusso più esterno chiamerà close() sui flussi avvolti. Tuttavia, se pensi che sia probabile che un costruttore lancerà un'eccezione, fare un uso liberale del Closeable interfaccia.

FileReader fr = new FileReader(fileName);
Closeable res = fr;
try {
    BufferedReader br = new BufferedReader(fr);
    res = br;
} finally {
    res.close();
}

Quindi, anche se il JVM si esaurisce lo spazio heap per il buffer e lanciasse un errore, non perdetti un manico di file.

Per Java 7 e oltre usa Try-With-Resurces:

try (FileReader fr = new FileReader(fileName);
    BufferedReader br = new BufferedReader(fr)) {
  // do work
}

Altri suggerimenti

Chiudendo solo il BufferedReader è sufficiente, perché avvolge il FileReader. Se guardi il codice sorgente di BufferedReader vedrai che il close Metodo, chiude il flusso avvolto.

Chiudi il bufferedReader in un blocco finalmente.

Se si chiama il metodo di chiusura del bufferedReader, il bufferedReader chiamerà il metodo chiuso del FileReader. Quindi vengono chiamati entrambi i metodi vicini. Più precisamente il bufferedReader non farà nulla MA Chiamare il metodo vicino del fileReader. Quindi non importa affatto. Anche se penso che sia anche una buona pratica, chiama il metodo vicino del bufferedReader.

Niente è garantito da non lanciare. Poiché il buffer viene assegnato, può lanciare OutfMemoryError. Di solito separo il mio codice in 2 sezioni: acquisire risorse e quindi uso risorse. Ogni sezione di solito ha esigenze di pulizia uniche

Ecco il codice per illustrare:

// Acquire resources section.

final FileReader fr = new FileReader( fileName );

BufferedReader br = null;

try
{
    br = new BufferedReader(fr);
}
finally
{
    if ( br == null )
    {
        // Note that you are closing the fr here
        fr.close( );
    }
}

// Use resources section
try
{
    // ... use br
}
finally
{
    // Now that br is safely constructed, just all its close
    br.close( );
}

E sono d'accordo con te, non c'è nulla di valido che perdere silenziosamente un gestore di file nell'applicazione del server a lungo termine.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top