SORU
2 ŞUBAT 2015, PAZARTESİ


İç içe geçmiş her OutputStream ayrı ayrı kapatmak için gerekli mi?

Kod parçasını yazıyorum:

OutputStream outputStream = new FileOutputStream(createdFile);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(gzipOutputStream));

Aşağıdaki gibi her dere veya yazar kapatmak gerekiyor mu?

gzipOutputStream.close();
bw.close();
outputStream.close();

Ya da sadece son derede kapanış iyi olacak?

bw.close();

CEVAP
2 ŞUBAT 2015, PAZARTESİ


Tüm akışları Tamam, evet, sadece bw kapanış oluşturulan varsayarsak gayet iyibu akış uygulamaları ile ilgili; ama bu büyük bir varsayım.

Kullanabilirsiniz try-with-resources (tutorial), böylece herhangi bir sorun inşa sonraki akıp atmak istisnalar bırakma önceki akışları asılı, ve zorunda kalmamak için itimat akışı uygulaması olan yakın temel akış:

try (
    OutputStream outputStream = new FileOutputStream(createdFile);
    GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
    OutputStreamWriter osw = new OutputStreamWriter(gzipOutputStream);
    BufferedWriter bw = new BufferedWriter(osw)
    ) {
    // ...
}

Artık close hiç unutmayın.

ÖNEMLİ NOT: Çalış-ile-kaynakları onlara yakın olmak zorundagerekironları açmak gibi değişkenler akışları atama yapamazsınız yuva kullanın. Eğer iç içe kullanırsanız, daha sonra dere (, GZIPOutputStream demek) inşaatı sırasında herhangi bir özel durum akışı içinde iç içe çağrıları tarafından inşa açık bırakacak. JLS §14.20.3:

Bir açıklama ile parametreli-ile-kaynakları deneyindeğişkenler(kaynak olarak da bilinir) try blok yürütme önce başlatılır ve otomatik olarak, try blok yürütme sonra hangi başlatıldı ters sırada kapattı.

Kelime not "değişken"(vurgu benim).

E. g., bunu yapma:

// DON'T DO THIS
try (BufferedWriter bw = new BufferedWriter(
        new OutputStreamWriter(
        new GZIPOutputStream(
        new FileOutputStream(createdFile))))) {
    // ...
}

...çünkü bir istisna GZIPOutputStream(OutputStream) kurucu IOException, atmak olabilir diyor ve temel Akış için bir başlık yazar) FileOutputStream açık bırakacaktı. Bazı kaynaklar bu yana var ve diğerleri yok, sadece onları ayrı ayrı listelemek için iyi bir alışkanlıktır atmak olabilir kurucular.

Çift kontrol Bu program ile bu İDEA bölüm bizim yorumu yapabiliriz:

public class Example {

    private static class InnerMost implements AutoCloseable {
        public InnerMost() throws Exception {
            System.out.println("Constructing "   this.getClass().getName());
        }

        @Override
        public void close() throws Exception {
            System.out.println(this.getClass().getName()   " closed");
        }
    }

    private static class Middle implements AutoCloseable {
        private AutoCloseable c;

        public Middle(AutoCloseable c) {
            System.out.println("Constructing "   this.getClass().getName());
            this.c = c;
        }

        @Override
        public void close() throws Exception {
            System.out.println(this.getClass().getName()   " closed");
            c.close();
        }
    }

    private static class OuterMost implements AutoCloseable {
        private AutoCloseable c;

        public OuterMost(AutoCloseable c) throws Exception {
            System.out.println("Constructing "   this.getClass().getName());
            throw new Exception(this.getClass().getName()   " failed");
        }

        @Override
        public void close() throws Exception {
            System.out.println(this.getClass().getName()   " closed");
            c.close();
        }
    }

    public static final void main(String[] args) {
        // DON'T DO THIS
        try (OuterMost om = new OuterMost(
                new Middle(
                    new InnerMost()
                    )
                )
            ) {
            System.out.println("In try block");
        }
        catch (Exception e) {
            System.out.println("In catch block");
        }
        finally {
            System.out.println("In finally block");
        }
        System.out.println("At end of main");
    }
}

...çıktı

Constructing Example$InnerMost
Constructing Example$Middle
Constructing Example$OuterMost
In catch block
In finally block
At end of main

close çağrıları vardır hiç unutmayın.

Biz main düzeltme:

public static final void main(String[] args) {
    try (
        InnerMost im = new InnerMost();
        Middle m = new Middle(im);
        OuterMost om = new OuterMost(m)
        ) {
        System.out.println("In try block");
    }
    catch (Exception e) {
        System.out.println("In catch block");
    }
    finally {
        System.out.println("In finally block");
    }
    System.out.println("At end of main");
}

sonra close uygun çağrıları alıyoruz:

Constructing Example$InnerMost
Constructing Example$Middle
Constructing Example$OuterMost
Example$Middle closed
Example$InnerMost closed
Example$InnerMost closed
In catch block
In finally block
At end of main

(Evet, InnerMost#close iki çağrıları doğru; Middle--kaynakları deneyin başka biri.)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • After Effects Tutorials w/ Mikey

    After Effect

    24 HAZİRAN 2009
  • dcigs

    dcigs

    9 EYLÜL 2006
  • Lin Steven

    Lin Steven

    17 EKİM 2006