SORU
30 NİSAN 2009, PERŞEMBE


Bir zaman aşımı ile bir İnputStream okumak mümkün mü?

Sorun, özellikle böyle bir yöntem yazmaktır

int maybeRead(InputStream in, long timeout)

dönüş değeri aynıdır.eğer veri 'zaman aşımı' milisaniye, ve -2 aksi takdirde. içinde (varsa) okuyun Bu yöntem döndürür önce, herhangi bir iş parçacığı kökenli çıkmak gerekir.

Tartışma çıkmasın diye konuyu java.ıo.Güneş tarafından belirtildiği gibi İnputStream, (herhangi bir Java versiyonu). Lütfen bu göründüğü kadar basit değildir. Aşağıda doğrudan Güneş belgeler tarafından desteklenen bazı gerçekler vardır.

  1. .() okuma yöntemi olmayan ınterruptible olabilir.

  2. Bir Okuyucu olarak İnputStream veya İnterruptibleChannel tüm bu sınıflar yapabilir çünkü bir faydası olmayacak kaydırma İnputStream arama yöntemleri. Eğer bu sınıfları kullanmak mümkün olsaydı, doğrudan aynı mantık İnputStream üzerinde yürüten bir çözüm yazmak mümkün olurdu.

  3. Her zaman için kabul edilebilir.() mevcut 0 verilecek.

  4. .() yakın bir yöntem blok ya da hiçbir şey yapamaz.

  5. Başka bir iş parçacığı öldürmek için genel bir yolu yoktur.

CEVAP
23 Mart 2012, Cuma


Akışı bir yuva Socket.setSoTimeout() kullanamazsınız () tarafından desteklenen değildir varsayarak, bu tür bir sorunu çözme standart bir şekilde İleride kullanmak için olduğunu düşünüyorum.

Sanırım şu ana akarsu var:

    ExecutorService executor = Executors.newFixedThreadPool(2);
    final PipedOutputStream outputStream = new PipedOutputStream();
    final PipedInputStream inputStream = new PipedInputStream(outputStream);

Bazı veriler daha sonra veri son yazı ve akış kapatmadan önce 5 saniye bekler yazan bir yazar var:

    Runnable writeTask = new Runnable() {
        @Override
        public void run() {
            try {
                outputStream.write(1);
                outputStream.write(2);
                Thread.sleep(5000);
                outputStream.write(3);
                outputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    executor.submit(writeTask);

Bu okuma normal bir şekilde aşağıdaki gibidir. Okuma bu 5'li tamamlanıncaya kadar veri için süresiz ve engeller:

    long start = currentTimeMillis();
    int readByte = 1;
    // Read data without timeout
    while (readByte >= 0) {
        readByte = inputStream.read();
        if (readByte >= 0)
            System.out.println("Read: "   readByte);
    }
    System.out.println("Complete in "   (currentTimeMillis() - start)   "ms");

çıkışları:

Read: 1
Read: 2
Read: 3
Complete in 5001ms

Eğer daha temel bir sorun varsa, yazar vermiyor gibi, okuyucu sonsuza kadar engellenebilir. Ben bir gelecekte okuma sararsan, o zaman şöyle: zaman aşımı kontrol edebilirim

    int readByte = 1;
    // Read data with timeout
    Callable<Integer> readTask = new Callable<Integer>() {
        @Override
        public Integer call() throws Exception {
            return inputStream.read();
        }
    };
    while (readByte >= 0) {
        Future<Integer> future = executor.submit(readTask);
        readByte = future.get(1000, TimeUnit.MILLISECONDS);
        if (readByte >= 0)
            System.out.println("Read: "   readByte);
    }

çıkışları:

Read: 1
Read: 2
Exception in thread "main" java.util.concurrent.TimeoutException
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:228)
    at java.util.concurrent.FutureTask.get(FutureTask.java:91)
    at test.InputStreamWithTimeoutTest.main(InputStreamWithTimeoutTest.java:74)

Bu TimeoutException yakalamak ve ne istersem onu yapabilirim.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Chilla Frilla™

    Chilla Frill

    7 Aralık 2006
  • paulandstorm

    paulandstorm

    4 EYLÜL 2006
  • Skrillex

    Skrillex

    6 NİSAN 2010