जावा में इनपुटस्ट्रीम को बाइट सरणी में बदलें


जवाबों:


1135

आप इसे और इसी तरह के कार्यों को संभालने के लिए Apache Commons IO का उपयोग कर सकते हैं ।

IOUtilsप्रकार एक को पढ़ने के लिए एक स्थिर विधि है InputStreamऔर एक वापसी byte[]

InputStream is;
byte[] bytes = IOUtils.toByteArray(is);

आंतरिक रूप से यह एक बनाता है ByteArrayOutputStreamऔर बाइट्स को आउटपुट पर कॉपी करता है, फिर कॉल करता है toByteArray()। यह 4KiB के ब्लॉक में बाइट्स कॉपी करके बड़ी फ़ाइलों को संभालता है।


188
कोड की 4 पंक्तियाँ लिखने की इच्छा के लिए, आपको लगता है कि 3-पार्टी निर्भरता आयात करना सार्थक है?
oxbow_lakes

217
यदि कोई लाइब्रेरी है जो आवश्यकता को संभालती है, और बड़ी फ़ाइलों के लिए प्रसंस्करण से संबंधित है, और अच्छी तरह से परीक्षण किया जाता है, तो निश्चित रूप से सवाल यह है कि मैं खुद क्यों लिखूंगा? जार केवल 107KB है और अगर आपको इसके लिए एक विधि की आवश्यकता है, तो आप दूसरों को भी उपयोग करने की संभावना रखते हैं
रिच सेलर

242
@oxbow_lakes: के चक्कर राशि पर विचार गलत इस सुविधा मैं अपना विकासक जीवन में देखा है के कार्यान्वयन, मुझे लगता है कि हाँ यह बहुत यह सही पाने के लिए बाहरी निर्भरता ज्यादा के लायक।
जोआचिम सॉर

17
क्यों नहीं जाना है और अपाचे कॉमन्स सामान जैसे FastArrayListया उनके नरम और कमजोर संदर्भ मैप्स पर एक नज़र डालें और मुझे बताएं कि यह लाइब्रेरी कितनी अच्छी तरह से "अच्छी तरह से जांची गई" है। यह
10

87
Apache commons-io के अलावा, Google Guava से बाइटस्ट्रीम क्लास देखें । InputStream is; byte[] filedata=ByteStreams.toByteArray(is);
माइकललोक

446

आपको अपने से प्रत्येक बाइट को पढ़ने InputStreamऔर इसे लिखने की आवश्यकता है ByteArrayOutputStream

फिर आप कॉल करके अंतर्निहित बाइट सरणी प्राप्त कर सकते हैं toByteArray():

InputStream is = ...
ByteArrayOutputStream buffer = new ByteArrayOutputStream();

int nRead;
byte[] data = new byte[16384];

while ((nRead = is.read(data, 0, data.length)) != -1) {
  buffer.write(data, 0, nRead);
}

return buffer.toByteArray();

16
नव निर्मित बाइट के आकार के बारे में क्या []। यह 16384 क्यों है? मैं सही सही आकार कैसे निर्धारित कर सकता हूं? आपका बहुत बहुत धन्यवाद।
ओन्ड्रेज बोजेक

6
16384 एक मनमानी विकल्प है, हालांकि मैं शब्द सीमाओं के साथ संरेखित सरणी की संभावना को बढ़ाने के लिए 2 की शक्तियों का पक्ष लेता हूं। pihentagy का जवाब दिखाता है कि आप एक मध्यवर्ती बफर का उपयोग करने से कैसे बच सकते हैं, बल्कि सही आकार की एक सरणी आवंटित कर सकते हैं। जब तक आप बड़ी फ़ाइलों के साथ काम नहीं कर रहे हैं मैं व्यक्तिगत रूप से ऊपर दिए गए कोड को पसंद करता हूं, जो अधिक सुरुचिपूर्ण है और इसका उपयोग इनपुटस्ट्रीम के लिए किया जा सकता है जहां पढ़ने के लिए बाइट्स की संख्या पहले से ज्ञात नहीं है।
अदाम्सकी

@ Adamski बाइट्स का सरणी नहीं बना रहा है जितना कि आप उम्मीद करते हैं कि डेटा स्ट्रीम में होगा, मेमोरी को बर्बाद करेगा?
16:37 पर पॉल ब्रूसकिनस्की

@bluesm: हाँ यह सही है। हालांकि, मेरे उदाहरण में बाइट सरणी केवल 16Kb है और आज के मानकों से बहुत कम है। इसके अलावा, निश्चित रूप से इस स्मृति को बाद में फिर से मुक्त किया जाएगा।
एडम्सकी

5
@ Adamski डेटा को स्थानांतरित करने के लिए बहुत सारे इन्फ्रास्ट्रक्चर हार्डवेयर, वेब-सर्वर और ओएस-लेयर घटक 4K बफ़र्स का उपयोग कर रहे हैं, इसलिए यह सटीक संख्या का कारण है, लेकिन मुख्य बिंदु यह है कि आपको 4K पर जाकर इस तरह के छोटे प्रदर्शन को बढ़ावा मिलता है यह आमतौर पर स्मृति की बर्बादी माना जाता है। मुझे लगता है कि यह अभी भी सच है, क्योंकि यह एक दशक पुराना ज्ञान है!

312

अंत में, बीस साल बाद, तीसरी पार्टी लाइब्रेरी की आवश्यकता के बिना एक सरल समाधान है, जावा 9 के लिए धन्यवाद :

InputStream is;

byte[] array = is.readAllBytes();

नोट भी सुविधा के तरीकों readNBytes(byte[] b, int off, int len)और transferTo(OutputStream)आवर्ती जरूरतों को संबोधित।


132

वेनिला जावा DataInputStreamऔर इसकी readFullyविधि का उपयोग करें (कम से कम जावा 1.4 के बाद से मौजूद है):

...
byte[] bytes = new byte[(int) file.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
dis.readFully(bytes);
...

इस पद्धति के कुछ अन्य स्वाद हैं, लेकिन मैं इस उपयोग के मामले के लिए हर समय उपयोग करता हूं।


45
एक 3 पार्टी निर्भरता के बजाय मानक पुस्तकालयों का उपयोग करने के लिए +1। दुर्भाग्य से यह मेरे लिए काम नहीं करता क्योंकि मुझे स्ट्रीम अपफ्रंट की लंबाई का पता नहीं है।
एंड्रयू स्पेंसर

2
imgFile क्या है? यह एक इनपुटस्ट्रीम नहीं हो सकता है, जिसे इस विधि का इनपुट माना जाता था
जानूस ट्रॉल्सन

4
@janus यह एक "फ़ाइल" है। यह तरीका केवल तभी काम करता है जब u फाइल की लंबाई या पढ़ने के लिए बाइट्स की गिनती जानता है।
dermoritz

5
दिलचस्प बात है, लेकिन आपको पढ़ने के लिए () के प्रवाह की सटीक लंबाई पता होनी चाहिए। इसके अलावा, क्लास DataInputStreamको प्राथमिक (Longs, Shorts, Chars ...) एक स्ट्रीम से पढ़ने के लिए उपयोग किया जाता है, इसलिए हम इस उपयोग को क्लास के दुरुपयोग के रूप में देख सकते हैं।
ओलिवियर फौचेक्स

17
यदि आप स्ट्रीम से पढ़ने के लिए पहले से ही डेटा की लंबाई जानते हैं, तो यह इससे बेहतर नहीं है InputStream.read
लोगन पिकअप


46

हमेशा की तरह, स्प्रिंग फ्रेमवर्क (3.2.2 के बाद से स्प्रिंग-कोर) आपके लिए कुछ है:StreamUtils.copyToByteArray()


अन्य लोगों की तरह, मैं कुछ आसान के लिए 3 जी लाइब्रेरी का उपयोग करने से बचना चाहता था, लेकिन जावा 9 इस समय कोई विकल्प नहीं है ... सौभाग्य से, मैं पहले से ही स्प्रिंग का उपयोग कर रहा था।
स्कोट्टीसस

42
public static byte[] getBytesFromInputStream(InputStream is) throws IOException {
    ByteArrayOutputStream os = new ByteArrayOutputStream(); 
    byte[] buffer = new byte[0xFFFF];
    for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { 
        os.write(buffer, 0, len);
    }
    return os.toByteArray();
}

2
यह एक उदाहरण है और इस तरह, संक्षिप्तता दिन का क्रम है। इसके अलावा यहाँ वापस आना कुछ मामलों में उचित विकल्प होगा (हालाँकि उत्पादन के माहौल में आपके पास उचित अपवाद हैंडलिंग और प्रलेखन भी होगा)।

11
मैं एक उदाहरण में संक्षिप्तता को समझता हूं, लेकिन केवल उदाहरण विधि को निगलने के बजाय IOException को क्यों नहीं फेंकना और व्यर्थ मान वापस करना?
पेंड्र

4
मैंने n रिटर्न नल ’से O IOException’ फेंकने की स्वतंत्रता को बदल दिया है
kritzikratzi

3
यहां कोशिश-के-संसाधनों की आवश्यकता नहीं है, क्योंकि बाइटएयरऑउटपुटस्ट्रीम # करीब () कुछ भी नहीं करता है। (ByteArrayOutputStream # फ्लश () की ज़रूरत नहीं है और कुछ भी नहीं करता है।)
ल्यूक हचिसन

25

सुरक्षित समाधान (closeधाराओं कीक्षमता के साथसही ढंग से):

  • जावा 9+ संस्करण:

    final byte[] bytes;
    try (inputStream) {
        bytes = inputStream.readAllBytes();
    }
  • जावा 8 संस्करण:

    public static byte[] readAllBytes(InputStream inputStream) throws IOException {
        final int bufLen = 4 * 0x400; // 4KB
        byte[] buf = new byte[bufLen];
        int readLen;
        IOException exception = null;
    
        try {
            try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                while ((readLen = inputStream.read(buf, 0, bufLen)) != -1)
                    outputStream.write(buf, 0, readLen);
    
                return outputStream.toByteArray();
            }
        } catch (IOException e) {
            exception = e;
            throw e;
        } finally {
            if (exception == null) inputStream.close();
            else try {
                inputStream.close();
            } catch (IOException e) {
                exception.addSuppressed(e);
            }
        }
    }
  • कोटलिन संस्करण (जब जावा 9+ सुलभ नहीं है):

    @Throws(IOException::class)
    fun InputStream.readAllBytes(): ByteArray {
        val bufLen = 4 * 0x400 // 4KB
        val buf = ByteArray(bufLen)
        var readLen: Int = 0
    
        ByteArrayOutputStream().use { o ->
            this.use { i ->
                while (i.read(buf, 0, bufLen).also { readLen = it } != -1)
                    o.write(buf, 0, readLen)
            }
    
            return o.toByteArray()
        }
    }

    नेस्टेड से बचने के useलिए यहां देखें ।


क्या इसका मतलब यह नहीं है कि किसी बिंदु पर आप उपयोग की गई मेमोरी को दोगुना कर देंगे, क्योंकि आपके पास बफर और बाइट दोनों सरणी हैं? क्या बाइट को सीधे आउटपुट बाइट सरणी में भेजने का कोई तरीका नहीं है?
एंड्रॉयड डेवलपर

@androiddeveloper; मुझे माफ कर दो। मैं जवाब नहीं जानता! लेकिन मुझे ऐसा नहीं लगता। मुझे लगता है कि इस तरह (बफर का उपयोग करके) एक अनुकूलित तरीका है।
मीर-इस्माइली

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

@androiddeveloper; आपकी जानकारी के लिए धन्यवाद। मैं उन्हें नहीं जानता था।
मीर-इस्माइली

19

क्या आपको वास्तव में छवि की आवश्यकता है byte[]? आप वास्तव में क्या उम्मीद करते हैं byte[]- एक छवि फ़ाइल की पूरी सामग्री, छवि फ़ाइल जो भी प्रारूप में है, या आरजीबी पिक्सेल मूल्यों में एन्कोडेड है?

अन्य उत्तर यहां आपको एक फ़ाइल को एक में पढ़ने का तरीका दिखाते हैं byte[]। आपकी byte[]फ़ाइल में सटीक सामग्री होगी, और आपको छवि डेटा के साथ कुछ भी करने की आवश्यकता होगी।

छवियों (पढ़ने और लिखने) के लिए जावा का मानक एपीआई इमेजियो एपीआई है, जिसे आप पैकेज में पा सकते हैं javax.imageio। आप कोड की केवल एक पंक्ति वाली फ़ाइल से किसी चित्र में पढ़ सकते हैं:

BufferedImage image = ImageIO.read(new File("image.jpg"));

यह आपको एक BufferedImageनहीं, एक देगा byte[]। छवि डेटा प्राप्त करने के लिए, आप getRaster()पर कॉल कर सकते हैं BufferedImage। यह आपको एक Rasterऑब्जेक्ट देगा, जिसमें पिक्सेल डेटा तक पहुंचने के तरीके हैं (इसमें कई getPixel()/ getPixels()तरीके हैं)।

API दस्तावेज़ देखने के लिए javax.imageio.ImageIO, java.awt.image.BufferedImage, java.awt.image.Rasterआदि

ImageIO डिफ़ॉल्ट रूप से कई छवि प्रारूपों का समर्थन करता है: JPEG, PNG, BMP, WBMP और GIF। अधिक स्वरूपों के लिए समर्थन जोड़ना संभव है (आपको ImageIO सेवा प्रदाता इंटरफ़ेस को प्लग-इन लागू करना होगा)।

निम्नलिखित ट्यूटोरियल भी देखें: छवियों के साथ काम करना


16

मामले में कोई अभी भी एक निर्भरता के बिना एक समाधान की तलाश कर रहा है और यदि आपके पास एक फ़ाइल है

1) DataInputStream

 byte[] data = new byte[(int) file.length()];
 DataInputStream dis = new DataInputStream(new FileInputStream(file));
 dis.readFully(data);
 dis.close();

2) बाइटएयरेऑटपुटस्ट्रीम

 InputStream is = new FileInputStream(file);
 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
 int nRead;
 byte[] data = new byte[(int) file.length()];
 while ((nRead = is.read(data, 0, data.length)) != -1) {
     buffer.write(data, 0, nRead);
 }

3) रैंडमअफाइलफाइल

 RandomAccessFile raf = new RandomAccessFile(file, "r");
 byte[] data = new byte[(int) raf.length()];
 raf.readFully(data);

कहो, क्या होगा यदि बाइट सरणी बहुत बड़ा है जो ढेर के लिए ओओएम का कारण बन सकता है? क्या एक समान समाधान है जो बाइट्स को स्टोर करने के लिए जेएनआई का उपयोग करेगा, और बाद में हम वहां संग्रहीत डेटा (अस्थायी कैश की तरह) से इनपुटस्ट्रीम का उपयोग करने में सक्षम होंगे?
एंड्रॉयड डेवलपर

14

यदि आप Apache commons-io लाइब्रेरी का उपयोग नहीं करना चाहते हैं, तो यह स्निपेट sun.misc.IOUilsils से लिया गया है। यह बाइटबफर्स ​​का उपयोग करते हुए आम कार्यान्वयन के रूप में लगभग दोगुना है:

public static byte[] readFully(InputStream is, int length, boolean readAll)
        throws IOException {
    byte[] output = {};
    if (length == -1) length = Integer.MAX_VALUE;
    int pos = 0;
    while (pos < length) {
        int bytesToRead;
        if (pos >= output.length) { // Only expand when there's no room
            bytesToRead = Math.min(length - pos, output.length + 1024);
            if (output.length < pos + bytesToRead) {
                output = Arrays.copyOf(output, pos + bytesToRead);
            }
        } else {
            bytesToRead = output.length - pos;
        }
        int cc = is.read(output, pos, bytesToRead);
        if (cc < 0) {
            if (readAll && length != Integer.MAX_VALUE) {
                throw new EOFException("Detect premature EOF");
            } else {
                if (output.length != pos) {
                    output = Arrays.copyOf(output, pos);
                }
                break;
            }
        }
        pos += cc;
    }
    return output;
}

यह एक अजीब समाधान है, लंबाई सरणी की लंबाई पर एक ऊपरी बाध्य है। यदि आप लंबाई जानते हैं, तो आपको बस जरूरत है: बाइट [] आउटपुट = नई बाइट [लंबाई]; is.read (उत्पादन); (लेकिन मेरा जवाब देखें)
ल्यूक हचिसन

@ luke-hutchison जैसा कि मैंने कहा, यह sun.misc.IOUtils का समाधान है। सबसे आम मामलों में आप एक इनपुटस्ट्रीम अपफ्रंट के आकार को नहीं जानते हैं, इसलिए यदि (लंबाई == -1) लंबाई = Integer.MAX_VALUE; लागू होता है। यह समाधान काम करता है, भले ही दी गई लंबाई इनपुटस्ट्रीम की लंबाई से बड़ी हो।
क्रिस्टियन क्रालिजिक

@LukeHutchison यदि आप लंबाई जानते हैं तो आप इसे कुछ पंक्तियों के साथ संभाल सकते हैं। यदि आप प्रत्येक उत्तर को देखते हैं, तो हर कोई शिकायत कर रहा है कि लंबाई ज्ञात नहीं है। अंत में एक उत्तर जो मानक है, जावा 7 एंड्रॉइड के साथ उपयोग किया जा सकता है, और इसके लिए किसी बाहरी पुस्तकालय की आवश्यकता नहीं है।
Csaba Toth

11
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
while (true) {
    int r = in.read(buffer);
    if (r == -1) break;
    out.write(buffer, 0, r);
}

byte[] ret = out.toByteArray();

8

@ एडम्सकी: आप पूरी तरह से बफर से बच सकते हैं।

Http://www.exampledepot.com/egs/java.io/File2ByteArray.html से कॉपी किया गया कोड (हां, यह बहुत ही क्रियात्मक है, लेकिन दूसरे समाधान के रूप में स्मृति के आधे आकार की आवश्यकता है।)

// Returns the contents of the file in a byte array.
public static byte[] getBytesFromFile(File file) throws IOException {
    InputStream is = new FileInputStream(file);

    // Get the size of the file
    long length = file.length();

    // You cannot create an array using a long type.
    // It needs to be an int type.
    // Before converting to an int type, check
    // to ensure that file is not larger than Integer.MAX_VALUE.
    if (length > Integer.MAX_VALUE) {
        // File is too large
    }

    // Create the byte array to hold the data
    byte[] bytes = new byte[(int)length];

    // Read in the bytes
    int offset = 0;
    int numRead = 0;
    while (offset < bytes.length
           && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
        offset += numRead;
    }

    // Ensure all the bytes have been read in
    if (offset < bytes.length) {
        throw new IOException("Could not completely read file "+file.getName());
    }

    // Close the input stream and return bytes
    is.close();
    return bytes;
}

5
आकार अपफ्रंट जानने पर निर्भर करता है।
स्टॉल्सविक

2
बेशक, लेकिन उन्हें आकार पता होना चाहिए: "मैं एक छवि पढ़ना चाहता हूं"
pihentagy

1
यदि आप आकार जानते हैं, तो जावा आपके लिए कोड प्रदान करता है। "DataInputStream" के लिए मेरा उत्तर या Google देखें और यह पूरी तरह से पढ़ी गई विधि है।
डर्मोरिट्ज

यदि अपवाद छोड़ दिया जाए is.close()तो आपको जोड़ना चाहिए offset < bytes.lengthया InputStreamबंद नहीं होगा।
जेरेड रुम्मलर

3
फिर बेहतर है, आपको कोशिश करनी चाहिए कि संसाधनों के साथ
pihentagy

8
Input Stream is ...
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int next = in.read();
while (next > -1) {
    bos.write(next);
    next = in.read();
}
bos.flush();
byte[] result = bos.toByteArray();
bos.close();

हालांकि, आमतौर पर ओएस पहले से ही इसके लिए पर्याप्त रूप से बफ़र करता है, छोटी फ़ाइलों के लिए एक बड़ी चिंता का विषय नहीं होना चाहिए। ऐसा नहीं है कि हार्ड डिस्क हेड प्रत्येक बाइट को अलग से पढ़ेगा (हार्ड डिस्क एक टर्निंग ग्लास प्लेट है जिस पर चुंबकीय कोडित जानकारी होती है, उस अजीब आइकन की तरह थोड़ा सा हम डेटा बचाने के लिए उपयोग करते हैं: पी)।
मार्टन बोडेवेस

6
@Maarten Bodewes: अधिकांश उपकरणों में एक प्रकार का ब्लॉक ट्रांसफर होता है, इसलिए हर रीड () वास्तव में डिवाइस की वास्तविक पहुंच का कारण नहीं होगा, लेकिन प्रदर्शन को मारने के लिए प्रति बाइट पर OS-call होना पहले से ही पर्याप्त है। जबकि लपेटकर InputStreamएक में BufferedInputStreamहै कि कोड से पहले ओएस-कॉल को कम करने और काफी प्रदर्शन कमियां कम होता है, कि कोड को अभी भी एक से दूसरे बफर से अनावश्यक मैनुअल नकल काम करेंगे।
Holger


2

मुझे पता है कि बहुत देर हो चुकी है लेकिन मुझे लगता है कि क्लीनर समाधान है जो अधिक पठनीय है ...

/**
 * method converts {@link InputStream} Object into byte[] array.
 * 
 * @param stream the {@link InputStream} Object.
 * @return the byte[] array representation of received {@link InputStream} Object.
 * @throws IOException if an error occurs.
 */
public static byte[] streamToByteArray(InputStream stream) throws IOException {

    byte[] buffer = new byte[1024];
    ByteArrayOutputStream os = new ByteArrayOutputStream();

    int line = 0;
    // read bytes from stream, and store them in buffer
    while ((line = stream.read(buffer)) != -1) {
        // Writes bytes from byte array (buffer) into output stream.
        os.write(buffer, 0, line);
    }
    stream.close();
    os.flush();
    os.close();
    return os.toByteArray();
}

4
आपको कोशिश-के-संसाधनों का उपयोग करना चाहिए।
विक्टर स्टैफ़ुसा

अंत में आपकी ख़ुशी को त्रुटियों के मामले में अंत में ब्लॉक करने की आवश्यकता होती है, अन्यथा यह एक स्मृति रिसाव का कारण बन सकता है।
MGDavies

2

जावा 8 तरीका ( बफ़रड्रेडर और एडम बायन के लिए धन्यवाद )

private static byte[] readFully(InputStream input) throws IOException {
    try (BufferedReader buffer = new BufferedReader(new InputStreamReader(input))) {
        return buffer.lines().collect(Collectors.joining("\n")).getBytes(<charset_can_be_specified>);
    }
}

ध्यान दें कि यह समाधान गाड़ी वापसी ('\ r') मिटा देता है और अनुचित हो सकता है।


4
के लिए है String। ओपी पूछ रहा है byte[]
फ्रोजनफायर

यह सिर्फ \rइतना नहीं है कि एक समस्या हो सकती है। यह विधि बाइट्स को वर्णों में वापस ले जाती है और फिर से वापस आती है (InputStreamReader के लिए डिफ़ॉल्ट वर्ण सेट का उपयोग करके)। कोई भी बाइट्स जो कि डिफ़ॉल्ट वर्ण एन्कोडिंग में मान्य नहीं हैं (जैसे, लिनक्स पर UTF-8 के लिए) भ्रष्ट हो जाएगा, संभवतः बाइट्स की संख्या भी बदल जाएगी।
सीन

ऐसा लगता है कि यह अच्छा उत्तर है, लेकिन पाठ-उन्मुख है। सावधान ग्राहक।
व्हीज़िल

1

मैंने कचरा डेटा लिखने के लिए फिक्स के साथ @ numan के उत्तर को संपादित करने की कोशिश की, लेकिन संपादन अस्वीकार कर दिया गया। हालांकि इस छोटे से कोड में कुछ भी शानदार नहीं है लेकिन मैं कोई और बेहतर जवाब नहीं देख सकता। यहाँ मेरे लिए सबसे ज्यादा मायने रखता है:

ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024]; // you can configure the buffer size
int length;

while ((length = in.read(buffer)) != -1) out.write(buffer, 0, length); //copy streams
in.close(); // call this in a finally block

byte[] result = out.toByteArray();

btw बाइटआर्टऑउटपुटस्ट्रीम को बंद करने की आवश्यकता नहीं है। कोशिश / अंत में पठनीयता के लिए छोड़ा गया निर्माण


1

InputStream.available()प्रलेखन देखें :

यह महसूस करना विशेष रूप से महत्वपूर्ण है कि कंटेनर को आकार देने के लिए आपको इस पद्धति का उपयोग नहीं करना चाहिए और यह मान लेना चाहिए कि आप कंटेनर को आकार देने के लिए बिना स्ट्रीम की संपूर्णता को पढ़ सकते हैं। इस तरह के कॉल करने वालों को शायद वह सब कुछ लिखना चाहिए जो वे एक बाइटअरेओट्यूटस्ट्रीमस्ट्रीम पर पढ़ते हैं और इसे बाइट ऐरे में बदल देते हैं। वैकल्पिक रूप से, यदि आप किसी फ़ाइल से पढ़ रहे हैं, तो File.length फ़ाइल की वर्तमान लंबाई लौटाती है (हालांकि यह मानते हुए कि फ़ाइल की लंबाई बदल नहीं सकती है, गलत है, फ़ाइल पढ़ना स्वाभाविक रूप से दुर्लभ है)।


1

एक DataInputStream में लपेटें यदि वह किसी कारण से तालिका से बाहर है, तो बस उस पर हथौड़े को पढ़ने का उपयोग करें जब तक कि यह आपको -1 या आपके द्वारा मांगे गए पूरे ब्लॉक को न दे।

public int readFully(InputStream in, byte[] data) throws IOException {
    int offset = 0;
    int bytesRead;
    boolean read = false;
    while ((bytesRead = in.read(data, offset, data.length - offset)) != -1) {
        read = true;
        offset += bytesRead;
        if (offset >= data.length) {
            break;
        }
    }
    return (read) ? offset : -1;
}

1

एस 3 ऑब्जेक्ट को बाइटएयर्रे में परिवर्तित करते हुए हम कुछ एडब्ल्यूएस लेनदेन के लिए कुछ देरी देख रहे हैं।

नोट: S3 ऑब्जेक्ट पीडीएफ दस्तावेज़ है (अधिकतम आकार 3 एमबी है)।

हम S3 ऑब्जेक्ट को ByteArray में बदलने के लिए # 1 (org.apache.commons.io.IOUtils) विकल्प का उपयोग कर रहे हैं। हमने S3 पर ध्यान दिया है कि S3 ऑब्जेक्ट को बाइटएयर्रे में परिवर्तित करने के लिए IOUtils विधि प्रदान करें, हम आपसे निवेदन करते हैं कि देरी से बचने के लिए S3 ऑब्जेक्ट को बाइटअवर में परिवर्तित करने का सबसे अच्छा तरीका क्या है।

विकल्प 1:

import org.apache.commons.io.IOUtils;
is = s3object.getObjectContent();
content =IOUtils.toByteArray(is);

विकल्प 2:

import com.amazonaws.util.IOUtils;
is = s3object.getObjectContent();
content =IOUtils.toByteArray(is);

मुझे यह भी बताएं कि क्या हमारे पास s3 ऑब्जेक्ट को बाईट्रेयर में बदलने का कोई और बेहतर तरीका है


0

सर्वर द्वारा अनुरोध भेजने और प्रतिक्रिया की प्रतीक्षा करने के बाद, स्ट्रीम के माध्यम से सही बाइट सरणी प्राप्त करने के लिए अन्य मामला।

/**
         * Begin setup TCP connection to PC app
         * to open integrate connection between mobile app and pc app (or mobile app)
         */
        mSocket = new Socket(IP, port);
       // mSocket.setSoTimeout(30000);

        DataOutputStream mDos = new DataOutputStream(mSocket.getOutputStream());

        String str = "MobileRequest#" + params[0] + "#<EOF>";

        mDos.write(str.getBytes());

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        /* Since data are accepted as byte, all of them will be collected in the
        following byte array which initialised with accepted data length. */
        DataInputStream mDis = new DataInputStream(mSocket.getInputStream());
        byte[] data = new byte[mDis.available()];

        // Collecting data into byte array
        for (int i = 0; i < data.length; i++)
            data[i] = mDis.readByte();

        // Converting collected data in byte array into String.
        String RESPONSE = new String(data);

0

यदि आप ByteArrayOutputStream का उपयोग करते हैं तो आप एक अतिरिक्त प्रतिलिपि बना रहे हैं। यदि आप इसे पढ़ना शुरू करने से पहले स्ट्रीम की लंबाई जानते हैं (जैसे InputStream वास्तव में एक FileInputStream है, और आप फ़ाइल पर file.length () कॉल कर सकते हैं, या InputStream एक zipfile प्रविष्टि InputStream है, और आप zipEntry को कॉल कर सकते हैं। लंबाई ()), तो बाइट में सीधे लिखना बेहतर है [] सरणी - यह आधी मेमोरी का उपयोग करता है, और समय बचाता है।

// Read the file contents into a byte[] array
byte[] buf = new byte[inputStreamLength];
int bytesRead = Math.max(0, inputStream.read(buf));

// If needed: for safety, truncate the array if the file may somehow get
// truncated during the read operation
byte[] contents = bytesRead == inputStreamLength ? buf
                  : Arrays.copyOf(buf, bytesRead);

एनबी अंतिम पंक्ति से संबंधित फ़ाइलों को काट रहा है, जबकि स्ट्रीम पढ़ी जा रही है, अगर आपको उस संभावना को संभालने की आवश्यकता है, लेकिन यदि स्ट्रीम पढ़ने के दौरान फ़ाइल लंबी हो जाती है , तो बाइट में सामग्री [] सरणी लंबी नहीं होगी। नई फ़ाइल सामग्री को शामिल करने के लिए, सरणी को केवल पुरानी लंबाई के इनपुटस्ट्रीम लैंथ से काट दिया जाएगा ।


0

मैं इसका उपयोग करता हूं।

public static byte[] toByteArray(InputStream is) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
            byte[] b = new byte[4096];
            int n = 0;
            while ((n = is.read(b)) != -1) {
                output.write(b, 0, n);
            }
            return output.toByteArray();
        } finally {
            output.close();
        }
    }

2
जवाब के साथ कुछ स्पष्टीकरण जोड़ें कि यह उत्तर ओपी को वर्तमान मुद्दे को ठीक करने में कैसे मदद करता है
ρяєρ withя K

0

यह मेरा कॉपी-पेस्ट संस्करण है:

@SuppressWarnings("empty-statement")
public static byte[] inputStreamToByte(InputStream is) throws IOException {
    if (is == null) {
        return null;
    }
    // Define a size if you have an idea of it.
    ByteArrayOutputStream r = new ByteArrayOutputStream(2048);
    byte[] read = new byte[512]; // Your buffer size.
    for (int i; -1 != (i = is.read(read)); r.write(read, 0, i));
    is.close();
    return r.toByteArray();
}

2
हालांकि यह कोड स्निपेट प्रश्न को हल कर सकता है, जिसमें स्पष्टीकरण सहित वास्तव में आपकी पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और उन लोगों को आपके कोड सुझाव के कारणों का पता नहीं चल सकता है।
फेरीबिग

0

जावा 7 और बाद में:

import sun.misc.IOUtils;
...
InputStream in = ...;
byte[] buf = IOUtils.readFully(in, -1, false);

20
sun.misc.IOUtils"जावा 7" नहीं है। यह एक मालिकाना, कार्यान्वयन विशिष्ट वर्ग है जो अन्य JRE कार्यान्वयन में मौजूद नहीं हो सकता है और अगले रिलीज में से किसी एक चेतावनी के बिना गायब हो सकता है।
होल्गर


0

यहाँ एक अनुकूलित संस्करण है, जो डेटा बाइट्स की नकल से यथासंभव बचने की कोशिश करता है:

private static byte[] loadStream (InputStream stream) throws IOException {
   int available = stream.available();
   int expectedSize = available > 0 ? available : -1;
   return loadStream(stream, expectedSize);
}

private static byte[] loadStream (InputStream stream, int expectedSize) throws IOException {
   int basicBufferSize = 0x4000;
   int initialBufferSize = (expectedSize >= 0) ? expectedSize : basicBufferSize;
   byte[] buf = new byte[initialBufferSize];
   int pos = 0;
   while (true) {
      if (pos == buf.length) {
         int readAhead = -1;
         if (pos == expectedSize) {
            readAhead = stream.read();       // test whether EOF is at expectedSize
            if (readAhead == -1) {
               return buf;
            }
         }
         int newBufferSize = Math.max(2 * buf.length, basicBufferSize);
         buf = Arrays.copyOf(buf, newBufferSize);
         if (readAhead != -1) {
            buf[pos++] = (byte)readAhead;
         }
      }
      int len = stream.read(buf, pos, buf.length - pos);
      if (len < 0) {
         return Arrays.copyOf(buf, pos);
      }
      pos += len;
   }
}

0

कोटलिन में समाधान (जावा में भी काम करेगा, निश्चित रूप से), जिसमें आप आकार जानते हैं या नहीं, दोनों मामले शामिल हैं:

    fun InputStream.readBytesWithSize(size: Long): ByteArray? {
        return when {
            size < 0L -> this.readBytes()
            size == 0L -> ByteArray(0)
            size > Int.MAX_VALUE -> null
            else -> {
                val sizeInt = size.toInt()
                val result = ByteArray(sizeInt)
                readBytesIntoByteArray(result, sizeInt)
                result
            }
        }
    }

    fun InputStream.readBytesIntoByteArray(byteArray: ByteArray,bytesToRead:Int=byteArray.size) {
        var offset = 0
        while (true) {
            val read = this.read(byteArray, offset, bytesToRead - offset)
            if (read == -1)
                break
            offset += read
            if (offset >= bytesToRead)
                break
        }
    }

यदि आप आकार जानते हैं, तो यह आपको अन्य समाधानों की तुलना में उपयोग की जाने वाली मेमोरी को दोगुना करने पर बचाता है (थोड़े समय में, लेकिन फिर भी उपयोगी हो सकता है)। ऐसा इसलिए है क्योंकि आपको संपूर्ण स्ट्रीम को अंत तक पढ़ना है, और फिर इसे बाइट सरणी (ArrayList के समान) में परिवर्तित करें जिसे आप केवल एक सरणी में परिवर्तित करते हैं)।

इसलिए, यदि आप Android पर हैं, उदाहरण के लिए, और आपको कुछ उड़ी संभालनी है, तो आप इसका उपयोग करके आकार प्राप्त करने का प्रयास कर सकते हैं:

    fun getStreamLengthFromUri(context: Context, uri: Uri): Long {
        context.contentResolver.query(uri, arrayOf(MediaStore.MediaColumns.SIZE), null, null, null)?.use {
            if (!it.moveToNext())
                return@use
            val fileSize = it.getLong(it.getColumnIndex(MediaStore.MediaColumns.SIZE))
            if (fileSize > 0)
                return fileSize
        }
        //if you wish, you can also get the file-path from the uri here, and then try to get its size, using this: https://stackoverflow.com/a/61835665/878126
        FileUtilEx.getFilePathFromUri(context, uri, false)?.use {
            val file = it.file
            val fileSize = file.length()
            if (fileSize > 0)
                return fileSize
        }
        context.contentResolver.openInputStream(uri)?.use { inputStream ->
            if (inputStream is FileInputStream)
                return inputStream.channel.size()
            else {
                var bytesCount = 0L
                while (true) {
                    val available = inputStream.available()
                    if (available == 0)
                        break
                    val skip = inputStream.skip(available.toLong())
                    if (skip < 0)
                        break
                    bytesCount += skip
                }
                if (bytesCount > 0L)
                    return bytesCount
            }
        }
        return -1L
    }

-1
/*InputStream class_InputStream = null;
I am reading class from DB 
class_InputStream = rs.getBinaryStream(1);
Your Input stream could be from any source
*/
int thisLine;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((thisLine = class_InputStream.read()) != -1) {
    bos.write(thisLine);
}
bos.flush();
byte [] yourBytes = bos.toByteArray();

/*Don't forget in the finally block to close ByteArrayOutputStream & InputStream
 In my case the IS is from resultset so just closing the rs will do it*/

if (bos != null){
    bos.close();
}

बंद करना और फ्लशिंग करना कीबोर्ड क्लिक की बर्बादी है। इनपुट स्ट्रीम को बंद करने से मदद मिलने की अधिक संभावना है। एक समय में एक बाइट पढ़ना अक्षम है। अंकन का उत्तर देखें।
एकोस्टाडिनोव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.