Soru Java 7'yi kullanarak kaynakları doğru kullanıyorum


Tamponlu okuyucuyu ve dosya okuyucuyu kapatmayı ve istisna atarsa ​​ortaya çıkan kaynakları bekliyorum.

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
    {
        return read(br);
    } 
}

Ancak, bir catch başarılı kapatma için yan tümce?

DÜZENLE:

Esasen, Java 7 için Java'ya eşdeğer olan yukarıdaki kod 7:

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{

    BufferedReader br = null;

    try
    {
        br = new BufferedReader(new FileReader(filePath));

        return read(br);
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        try
        {
            if (br != null) br.close();
        }
        catch(Exception ex)
        {
        }
    }

    return null;
}

76
2017-07-15 09:32


Menşei


Sorunuzu tekrar okuduktan sonra, iyi anladığımdan emin değilim. Açıklayabilir misiniz lütfen? - Maroun
Merhaba. Çita, ilk rolünü anlamaya çalışıyorum catch Java için örneğiniz 6. I.e. catch (Exception ex) { throw ex; } - sadece istisnayı yeniden atıyor, hiçbir şey yapmıyor, zarar görmeden kolayca çıkarılabiliyor. Yoksa bir şey mi özlüyorum? - Sasha
Sözdiziminde yanlış bir şey yok. Kaynaklarla çalışmayla ilgili daha fazla bilgi edinmek isterseniz, şu makaleye göz atın: Java kaynakları ile dene - Hussein Terek


Cevaplar:


Doğru ve gerek yok. catch fıkra. Oracle java 7 doc, kaynağın kapatılacağını söyledi ne olursa olsun Bir istisnanın gerçekten atılıp atılmadığı.

Kullanmalısın catch Sadece istisna üzerine tepki vermek istiyorsanız yan tümce. catch fıkra yürütülür sonra kaynak kapalı.

İşte bir snippet Oracle'ın öğreticisi:

Aşağıdaki örnek, bir dosyadan ilk satırı okur. Kullanır   BufferedReader örneğinden dosyadan veri okuma. BufferedReader   Program bittikten sonra kapatılması gereken bir kaynaktır   o:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
} // In this example, the resource declared in the try-with-resources statement is a BufferedReader.

... Çünkü BufferedReader örneği bir   try-with-resource deyimi, olup olmadığına bakılmaksızın kapatılacak   try ifadesi normal veya aniden tamamlanır.   Bir IOException atama yöntemi BufferedReader.readLine).

DÜZENLE

Yeni düzenlenmiş soruyla ilgili olarak:

Java 6'daki kod yürütülür. catch ve daha sonra finally blok. Bu, kaynakların hala potansiyel olarak açılmasına neden olur. catch blok.

Java 7 sözdiziminde kaynaklar kapalı önce  catch blok, bu yüzden kaynaklar zaten kapalı catch blok yürütme. Bu, yukarıdaki bağlantıda belgelenmiştir:

Kaynakla yapılan bir deyimde, herhangi bir yakalama veya sonuncu blok çalıştırılır   beyan edilen kaynaklar kapatıldıktan sonra.


94
2017-07-15 09:40





Bu durumda, kaynaklarla çalışmayı iyi kullanacaksınız, ancak genel olarak doğru değil. Bunun gibi kaynakları zincirlememelisiniz çünkü hoş olmayan sürprizlere yol açabilir. Değişken bir arabellek boyutuna sahip olduğunuzu varsayalım:

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    int sz = /* get buffer size somehow */
    try (BufferedReader br = new BufferedReader(new FileReader(filePath), sz))
    {
        return read(br);
    } 
}

Bir şeyin yanlış gittiğini varsayalım ve sz Olumsuz Bu durumda dosya kaynağınız ( new FileReader(filePath)) irade DEĞİL kapalı ol.

Bu sorunu önlemek için her bir kaynağı ayrı ayrı belirtmelisiniz:

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    int sz = /* get buffer size somehow */
    try (FileReader file = new FileReader(filePath);
         BufferedReader br = new BufferedReader(file, sz))
    {
        return read(br);
    } 
}

Bu durumda başlangıçta olsa bile br başarısız file hala kapalı. Daha fazla bilgi bulabilirsiniz İşte ve İşte.


65
2018-01-25 09:37



Kaynağın neden yaratıldığını anlamaya çalışıyorum new FileReader(filePath)) bir durumda kapatmak olmaz IllegalArgumentException sz negatif olduğunda atılır. Kaynaklarla denemeler, tüm kaynakları kapatmaz AutoClosable atılan istisnalar ne olursa olsun kaynaklar? - Prasoon Joshi
@PrasoonJoshi Hayır, sadece aramalar .close() try-with-sources başlatıcısı içinde bildirilen değişkenler için. Bu yüzden bu örnekte iki deklarasyona ayırmak hile yapar. - Mario Carneiro
Andrii ve @Mario Siz hem doğru hem yanlışsınız. İlk örnekte, FileReader, kaynakla çalışma mantığı tarafından kapatılmaz. Ancak, BufferedReader kapatıldığında, sarılmış FileReader'ı da kapatacaktır. Kanıt için java.io.BufferedReader.close () kaynağına bir göz atın. Sonuç olarak, ilk örnek kod tercih edilmelidir, çünkü daha özlüdür. - jschreiner
@jschreiner Doğru, her ne kadar Andrii (biraz contrived) sorunu sz < 0 kurucunun bir istisna atmasına neden olur, aslında kaynağın sızmasına neden olur. - Mario Carneiro
@mario Katılıyorum. Dış kurucu başarısız olabilir ve iç kaynak sızardı. Bunu daha önce görmedim, teşekkürler. - jschreiner