2010-05-22 15 views
9

मैं एक इनपुटस्ट्रीम बनाना चाहता हूं जो फ़ाइल में बाइट्स की एक निश्चित सीमा तक सीमित है, उदा। स्थिति 0 से 100 तक बाइट्स के लिए। ताकि क्लाइंट कोड ईओएफ को 100 वें बाइट तक पहुंचने के बाद देखना चाहिए।मैं फ़ाइल के केवल हिस्से को पढ़ने के लिए बाध्य इनपुट इनपुट कैसे बना सकता हूं?

उत्तर

10

read()InputStream की विधि एक समय में एक बाइट पढ़ती है। आप InputStream का उप-वर्ग लिख सकते हैं जो आंतरिक काउंटर को बनाए रखता है; प्रत्येक बार read() कहा जाता है, काउंटर अपडेट करें। यदि आपने अपना अधिकतम हिट किया है, तो आगे पढ़ने की अनुमति न दें (वापसी -1 या ऐसा कुछ)। (: सिर्फ UnsupportedOperationException फेंक उन्हें ओवरराइड और() पूर्व);

तुम भी सुनिश्चित करना है कि read_int पढ़ने, आदि के लिए अन्य तरीकों असमर्थित हैं की आवश्यकता होगी

मुझे नहीं पता कि आपका उपयोग केस क्या है, लेकिन बोनस के रूप में आप बफरिंग को भी लागू करना चाहते हैं।

+3

मुझे नहीं लगता कि बफरिंग को लागू करने की कोई आवश्यकता है - यह मिश्रण की चिंता है, और जिस तरह से पढ़ा जाता है (बाइट []) काम करता है, आवश्यक मात्रा में डेटा लौटता है, यह अनावश्यक बनाता है। यह BufferedInputStream में बेस स्ट्रीम को लपेटने के लिए क्लीनर और समान रूप से प्रभावी है। – mdma

+0

भी एनबी कि इनपुटस्ट्रीम में एकमात्र विधियों को सार घोषित किया जाता है() और पढ़ा जाता है (बाइट [], int, int) तो कभी-कभी आप अपने बच्चे वर्ग में केवल 2 (प्लस शायद क्लोज़()) को परिभाषित करने से दूर हो सकते हैं । – rogerdpack

2

यदि आपको केवल 100 बाइट्स की आवश्यकता है, तो सरल शायद सबसे अच्छा है, मैं उन्हें एक सरणी में पढ़ता हूं और इसे बाइटएरे इनपुट इनपुट के रूप में लपेटता हूं। जैसे

int length = 100; 
    byte[] data = new byte[length]; 
    InputStream in = ...; //your inputstream 
    DataInputStream din = new DataInputStream(din); 
    din.readFully(data); 
    ByteArrayInputStream first100Bytes = new ByteArrayInputStream(data); 
    // pass first100bytes to your clients 

आप DataInputStream.readFully का उपयोग नहीं करना चाहते हैं, तो Apache Commons-कब से IOUtils.readFully है, या आप पढ़ने के पाश स्पष्ट implment कर सकते हैं।

यदि आपके पास फ़ाइल के बीच में सेगमेंट से पढ़ने या डेटा की बड़ी मात्रा में पढ़ने के लिए अधिक उन्नत आवश्यकताएं हैं, तो इनपुटस्ट्रीम को विस्तारित करना और पढ़ने (बाइट [], int, int) को ओवरराइड करना और साथ ही पढ़ना(), आपको पढ़ने() विधि को ओवरराइड करने से बेहतर प्रदर्शन प्रदान करेगा।

8

danben says के रूप में, बस अपनी स्ट्रीम सजाने और बाधा लागू:

public class ConstrainedInputStream extends InputStream { 
    private final InputStream decorated; 
    private long length; 

    public ConstrainedInputStream(InputStream decorated, long length) { 
    this.decorated = decorated; 
    this.length = length; 
    } 

    @Override public int read() throws IOException { 
    return (length-- <= 0) ? -1 : decorated.read(); 
    } 

    // TODO: override other methods if you feel it's necessary 
    // optionally, extend FilterInputStream instead 
} 
+0

कोड पुन: उपयोग (कॉमन्स-io से BoundedInputStream): http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/BoundedInputStream.html – CelinHC

2

आप अमरूद के ByteStreams उपयोग कर सकते हैं पर विचार करें। सूचना है कि आप सीमा से पहले skipFully() का उपयोग करना चाहिए, उदाहरण के लिए:

ByteStreams.skipFully(tmpStream, range.start()); 
tmpStream = ByteStreams.limit(tmpStream, range.length()); 
1

इसके अलावा this समाधान के लिए, एक InputStream की skip पद्धति का उपयोग करके, आप भी फ़ाइल के बीच में एक सीमा के प्रारंभिक पढ़ सकते हैं।

public class RangeInputStream extends InputStream 
{ 
    private InputStream parent; 
    private long remaining; 

    public RangeInputStream(InputStream parent, long start, long end) throws IOException 
    { 
     if (end < start) 
     { 
      throw new IllegalArgumentException("end < start"); 
     } 

     if (parent.skip(start) < start) 
     { 
      throw new IOException("Unable to skip leading bytes"); 
     } 

     this.parent=parent; 
     remaining = end - start; 
    } 

    @Override 
    public int read() throws IOException 
    { 
     return --remaining >= 0 ? parent.read() : -1; 
    } 
} 
0

मैं अपने प्रोजेक्ट के लिए एक समान समस्या हल हो गया था, आप काम कर कोड यहाँ PartInputStream देख सकते हैं। मैं इसे संपत्तियों और फ़ाइलों इनपुट इनपुट के लिए इस्तेमाल किया गया था। लेकिन यह उन धाराओं के लिए उपयुक्त नहीं है जिनकी लंबाई प्रारंभ में उपलब्ध नहीं है, जैसे कि नेटवर्क स्ट्रीम।

संबंधित मुद्दे

 संबंधित मुद्दे