2008-12-13 19 views
9

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

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

उत्तर

8

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

शायद एक उत्तर विरासत की बजाय संरचना का उपयोग करना है (जिसे वैसे भी अनुशंसित अभ्यास है)। एक पाइप बनाएं जिसमें एक PipedInputStream और एक PipedOutputStream है जो getInputStream() और getOutputStream() विधियों के साथ एक दूसरे से जुड़ा हुआ है।

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

क्या यह आपके लिए काम करता है?

+2

आमेन! – Wivani

+0

आप पाइप में PipedInputStream और एक PipedOutputStream कैसे जोड़ते हैं और उन्हें कनेक्ट करते हैं? – Sabobin

3

ऐसा करने के लिए यह एक आम बात है, मुझे लगता है। यह सवाल देखें।

Easy way to write contents of a Java InputStream to an OutputStream

+0

I PipedXxxStream के बारे में जानें ... लेकिन मैं केवल एक पाइप ऑब्जेक्ट बनाना चाहता था जिसे एक थ्रेड पर इनपुटस्ट्रीम के रूप में और आउटपुटस्ट्रीम को दूसरे में दिया जा सकता था। उम्मीद कर रहा था कि मैंने कुछ याद किया होगा। – Baginsss

+0

ऐसा कुछ लिखना बहुत कठिन नहीं होगा जो आपको इनपुटस्ट्रीम दे सकता है जो आउटपुटस्ट्रीम पर पाइप करता है, लेकिन आप इनपुटस्ट्रीम और आउटपुटस्ट्रीम दोनों को विस्तारित नहीं कर पाएंगे। विरासत, बुरा। संरचना, अच्छा। – Apocalisp

5

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

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

1

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

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

तो Apocalisp का उत्तर सही है: आपको एक प्रतिलिपि लूप लिखना होगा।

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

+0

आप बफर साझा करते समय इनपुट और आउटपुट स्ट्रीम दोनों को उजागर करने वाले एक वर्ग के समान कुछ प्राप्त करने के लिए आंतरिक कक्षाओं का उपयोग कर सकते हैं। रचना के लिए – Charlie

0

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

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; 
       } 
      } 
    ); 
    } 
संबंधित मुद्दे