java दरग जावा में इनपुट और आउटपुट स्ट्रीम पाइप




क्या इनपुट और आउटपुट डिवाइस के बीच अंतर है (5)

यह एक बहुत ही आम बात है, मुझे लगता है। यह प्रश्न देखें

एक जावा इनपुटस्ट्रीम की आउटपुट स्ट्रीम में सामग्री लिखने का आसान तरीका

जावा में एक पाइप ऑब्जेक्ट बनाने के लिए किसी भी अच्छे सुझाव हैं, जो कि एक इनपुटस्ट्रीम और आउटपुटस्ट्रीम है क्योंकि जावा में एकाधिक विरासत नहीं है और दोनों स्ट्रीम इंटरफेस की बजाय अमूर्त वर्ग हैं?

अंतर्निहित आवश्यकता के लिए एक ऐसा ऑब्जेक्ट होना होता है जिसे चीजों को पारित किया जा सकता है, जो किसी इनपुट या स्ट्रीम को एक आउटपुट स्ट्रीम को एक थ्रेड से दूसरे इनपुट के लिए इनपुट की आवश्यकता होती है।


java.io.PipedOutputStream और java.io.PipedInputStream इस परिदृश्य के लिए उपयोग करने के लिए कक्षाओं को देखें वे धागे के बीच पाइप डेटा के साथ एक साथ उपयोग करने के लिए डिज़ाइन किए गए हैं।

यदि आप वास्तव में चाहते हैं कि किसी एकल ऑब्जेक्ट को पास करना है, तो इनमें से प्रत्येक में से एक को शामिल करना होगा और उन्हें गेटर्स के माध्यम से उजागर करना होगा।


आप एक ऐसा वर्ग नहीं बना सकते हैं जो InputStream और OutputStream दोनों से प्राप्त होता है क्योंकि इन इंटरफेस नहीं हैं और उनके पास सामान्य तरीके हैं और जावा एकाधिक वंशानुक्रमों की अनुमति नहीं देता (संकलक को पता नहीं है कि InputStream.close() या OutputStream.close() को कॉल करना है या नहीं OutputStream.close() close() करें OutputStream.close() अगर आप अपने नए ऑब्जेक्ट पर close() कॉल करते हैं

दूसरी समस्या बफर है जावा डेटा के लिए एक स्थिर बफर आवंटित करना चाहता है (जो परिवर्तित नहीं होता है) इसका अर्थ है कि जब आप 'java.io.PipedXxxstream' का उपयोग करते हैं, तब तक लेखन डेटा इसे अंततः ब्लॉक करेगा जब तक कि आप दो अलग थ्रेड्स का उपयोग न करें।

तो एपोकलिसप का जवाब सही है: आपको एक कॉपी लूप लिखना चाहिए।

मैं सुझाव देता हूं कि आप अपाचे के कॉमन्स-इन को अपने प्रोजेक्ट में शामिल करते हैं जिसमें कई सहायक रूटीन होते हैं, जैसे कि इस तरह के कार्यों के लिए (स्ट्रीम, फाइल, स्ट्रिंग्स और सभी संयोजनों के बीच डेटा कॉपी करें)।


मुझे Servlets के धीमे कनेक्शन के लिए एक फ़िल्टर लागू करना था, इसलिए मूल रूप से मैंने सर्व आउटलेट स्ट्रीम को एक क्व्यूऑउटपुटस्ट्रीम में लपेट कर दिया जो प्रत्येक बाइट (छोटे बफ़र्स) में एक कतार में जोड़ देगा, और फिर उन छोटे बफ़र्स को दूसरी आउटपुट स्ट्रीम में आउटपुट कर देगा एक तरह से यह इनपुट / आउटपुट स्ट्रीम के रूप में कार्य करता है, आईएमएचओ यह जेडीके पाइपों से बेहतर है जो कि अच्छी तरह से स्केल नहीं करेगा, मूल रूप से मानक जेडीके कार्यान्वयन (प्रति पठन / लिखना) में बहुत अधिक संदर्भ स्विचिंग है, एक अवरुद्ध कतार एक एकल उत्पादक / उपभोक्ता परिदृश्य के लिए आदर्श:

import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.*;

public class QueueOutputStream extends OutputStream
{
  private static final int DEFAULT_BUFFER_SIZE=1024;
  private static final byte[] END_SIGNAL=new byte[]{};

  private final BlockingQueue<byte[]> queue=new LinkedBlockingDeque<>();
  private final byte[] buffer;

  private boolean closed=false;
  private int count=0;

  public QueueOutputStream()
  {
    this(DEFAULT_BUFFER_SIZE);
  }

  public QueueOutputStream(final int bufferSize)
  {
    if(bufferSize<=0){
      throw new IllegalArgumentException("Buffer size <= 0");
    }
    this.buffer=new byte[bufferSize];
  }

  private synchronized void flushBuffer()
  {
    if(count>0){
      final byte[] copy=new byte[count];
      System.arraycopy(buffer,0,copy,0,count);
      queue.offer(copy);
      count=0;
    }
  }

  @Override
  public synchronized void write(final int b) throws IOException
  {
    if(closed){
      throw new IllegalStateException("Stream is closed");
    }
    if(count>=buffer.length){
      flushBuffer();
    }
    buffer[count++]=(byte)b;
  }

  @Override
  public synchronized void write(final byte[] b, final int off, final int len) throws IOException
  {
    super.write(b,off,len);
  }

  @Override
  public synchronized void close() throws IOException
  {
    flushBuffer();
    queue.offer(END_SIGNAL);
    closed=true;
  }

  public Future<Void> asyncSendToOutputStream(final ExecutorService executor, final OutputStream outputStream)
  {
    return executor.submit(
            new Callable<Void>()
            {
              @Override
              public Void call() throws Exception
              {
                try{
                  byte[] buffer=queue.take();
                  while(buffer!=END_SIGNAL){
                    outputStream.write(buffer);
                    buffer=queue.take();
                  }
                  outputStream.flush();
                } catch(Exception e){
                  close();
                  throw e;
                } finally{
                  outputStream.close();
                }
                return null;
              }
            }
    );
  }





multiple-inheritance