InputStream ජාවා හි බයිට් අරාව බවට පරිවර්තනය කරන්න


Answers:


1163

මේ හා සමාන කාර්යයන් හැසිරවීමට ඔබට Apache Commons IO භාවිතා කළ හැකිය .

මෙම IOUtilsවර්ගය සඳහා කියවීමට ස්ථිතික ක්රමය ඇති InputStreamඅතර නැවත byte[].

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

අභ්‍යන්තරව මෙය a නිර්මාණය කර ByteArrayOutputStreamබයිට් ප්‍රතිදානයට පිටපත් කර ඇමතුම් ලබා ගනී toByteArray(). එය 4KiB බ්ලොක් වල බයිට් පිටපත් කිරීමෙන් විශාල ගොනු හසුරුවයි.


194
කේත පේළි 4 ක් ලිවීමේ අවශ්‍යතාවය සඳහා, තෙවන පාර්ශවීය යැපීමක් ආනයනය කිරීම වටී යැයි ඔබ සිතනවාද?
oxbow_lakes

222
අවශ්‍යතාවය හසුරුවන පුස්තකාලයක් තිබේ නම් සහ විශාල ලිපිගොනු පිරිසැකසුම් කිරීම හා හොඳින් පරීක්‍ෂා කර තිබේ නම්, නිසැකවම ප්‍රශ්නය වන්නේ මා එය ලිවීමට හේතුව කුමක්ද? බඳුන 107KB පමණක් වන අතර ඔබට එයින් එක් ක්‍රමයක් අවශ්‍ය නම්, ඔබ අනෙක් ඒවා ද භාවිතා කිරීමට ඉඩ ඇත
පොහොසත් විකුණුම්කරු

245
@oxbow_lakes: අති මහත් ප්රමාණයක් සලකා වැරදි මම මගේ සංවර්ධක ජීවිතයේ දැකලා තියෙනවා මෙම විශේෂාංගය සඳහා, කියලා මට දැනෙනවා ඔව් ඒක ඉතා බාහිර පරායත්ත එය අයිතිය ලබා ගැනීමට බොහෝ වටිනවා.
ජෝකිම් සෝවර්

17
අපාචේ කොමන්ස් වැනි දේවල් FastArrayListහෝ ඒවායේ මෘදු හා දුර්වල යොමු සිතියම් දෙස බලා මෙම පුස්තකාලය කෙතරම් “හොඳින් පරීක්ෂා කර ඇත්දැයි” මට කියන්න. එය කුණු
ගොඩකි

87
Apache commons-io ට අමතරව, ගූගල් ගුවා වෙතින් බයිට්ස්ට්‍රීම් පන්තිය බලන්න . InputStream is; byte[] filedata=ByteStreams.toByteArray(is);
මයිකල්

455

ඔබ ඔබේ එක් එක් බයිටය කියවා InputStreamඑය a ට ලිවිය යුතුය 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();

17
අලුතින් සාදන ලද බයිට් ප්‍රමාණය ගැන කුමක් කිව හැකිද? එය 16384 වන්නේ ඇයි? නිවැරදි ප්‍රමාණය තීරණය කරන්නේ කෙසේද? බොහොම ස්තූතියි.
ඔන්ඩ්‍රෙජ් බොසෙක්

6
16384 තරමක් අත්තනෝමතික තේරීමක් වන නමුත් වචන සීමාවන් සමඟ අරාව පෙළගැස්වීමේ අවස්ථාව වැඩි කිරීම සඳහා මම 2 බලයට කැමැත්තක් දක්වමි. pihentagy හි පිළිතුර මඟින් ඔබට අතරමැදි බෆරයක් භාවිතා කිරීමෙන් වළක්වා ගත හැකි ආකාරය පෙන්වයි, නමුත් නිවැරදි ප්‍රමාණයේ පෙළක් වෙන් කරන්න. ඔබ විශාල ලිපිගොනු සමඟ ගනුදෙනු නොකරන්නේ නම්, මම පෞද්ගලිකව ඉහත කේතයට වැඩි කැමැත්තක් දක්වන්නෙමි, එය වඩාත් අලංකාර වන අතර කියවීමට බයිට් ගණන කල්තියා නොදන්නා InputStreams සඳහා භාවිතා කළ හැකිය.
ඇඩම්ස්කි

D ඇඩම්ස්කි දත්ත ප්‍රවාහයේ ඇතැයි ඔබ සිතනවාට වඩා විශාල බයිට් පෙළක් නිර්මාණය කිරීම නොවේද?
පෝල් බ rew ක්සින්ස්කි

lbluesm: ඔව් ඒක හරි. කෙසේ වෙතත්, මගේ උදාහරණයේ දී බයිට් අරා 16Kb පමණක් වන අතර වර්තමාන ප්‍රමිතීන්ට අනුව එය ඉතා කුඩාය. එසේම, ඇත්ත වශයෙන්ම මෙම මතකය පසුව නැවත නිදහස් වනු ඇත.
ඇඩම්ස්කි

5
D ඇඩම්ස්කි බොහෝ යටිතල පහසුකම් දෘඩාංග, වෙබ් සේවාදායක සහ OS-layer සංරචක දත්ත ගෙනයාමට 4K බෆර භාවිතා කරයි, එබැවින් නිශ්චිත සංඛ්‍යාවට හේතුව එයයි, නමුත් ප්‍රධාන කරුණ නම් 4K ඉක්මවා යාමෙන් ඔබට එතරම් කාර්ය සාධනයක් නොලැබීමයි. එය සාමාන්‍යයෙන් මතකය නාස්ති කිරීමක් ලෙස සැලකේ. මම හිතන්නේ මෙය තවමත් සත්‍යයක්, මන්ද එය මා සතුව තිබූ දශකයක පැරණි දැනුමයි!

325

අවසාන වශයෙන්, අවුරුදු විස්සකට පසු, තෙවන පාර්ශවීය පුස්තකාලයක අවශ්‍යතාවයකින් තොරව සරල විසඳුමක් ඇත, ජාවා 9 ට ස්තූතියි :

InputStream is;

byte[] array = is.readAllBytes();

පහසුව readNBytes(byte[] b, int off, int len)සහ transferTo(OutputStream)පුනරාවර්තන අවශ්‍යතා සපුරාලීම ද සැලකිල්ලට ගන්න .


134

වැනිලා ජාවා DataInputStreamසහ එහි readFullyක්‍රමය භාවිතා කරන්න (අවම වශයෙන් ජාවා 1.4 සිට පවතී):

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

මෙම ක්‍රමයේ තවත් රසයන් කිහිපයක් ඇත, නමුත් මම මෙම භාවිතය සඳහා සෑම විටම මෙය භාවිතා කරමි.


46
තෙවන පාර්ශවීය යැපීමක් වෙනුවට සම්මත පුස්තකාල භාවිතා කිරීම සඳහා +1. අවාසනාවට එය මට වැඩ කරන්නේ නැත, මන්දයත් මම දොළේ දිග ප්‍රමාණය නොදනිමි.
ඇන්ඩ rew ස්පෙන්සර්

2
imgFile යනු කුමක්ද? එය InputStream එකක් විය නොහැක, එය මෙම ක්‍රමයේ ආදානය විය යුතුය
Janus Troelsen

4
anjanus එය "ගොනුවක්" වේ. මෙම ක්‍රමය ක්‍රියාත්මක වන්නේ ඔබ ගොනුවේ දිග හෝ කියවිය යුතු බයිට් ගණන දන්නේ නම් පමණි.
ඩර්මොරිට්ස්

6
සිත්ගන්නා කරුණ, නමුත් කියවීමට (ධාරාවේ කොටස) නිශ්චිත දිග ඔබ දැන සිටිය යුතුය. එපමණක් නොව, පංතිය DataInputStreamප්‍රාථමික වශයෙන් (දිගු, කොට කලිසම්, අක්ෂර ...) ප්‍රවාහයකින් කියවීමට භාවිතා කරයි, එබැවින් අපට මෙම භාවිතය පන්තිය අනිසි ලෙස භාවිතා කිරීමක් ලෙස දැකිය හැකිය.
ඔලිවියර් ෆවුචියුක්ස්

18
ප්‍රවාහයෙන් කියවිය යුතු දත්තවල දිග ඔබ දැනටමත් දන්නවා නම්, මෙය වඩා හොඳ නොවේ InputStream.read.
ලෝගන් පිකප්


51

සෑම විටම මෙන්, වසන්ත රාමුවට (3.2.2 සිට වසන්ත-හරය) ඔබට යමක් තිබේ:StreamUtils.copyToByteArray()


අනෙක් බොහෝ අය මෙන්, මට අවශ්‍ය වූයේ තුන්වන පාර්ශවීය පුස්තකාලයක් එතරම් සරල දෙයක් සඳහා භාවිතා කිරීමෙන් වළකින්න, නමුත් ජාවා 9 මේ මොහොතේ විකල්පයක් නොවේ ... වාසනාවකට මෙන්, මම දැනටමත් වසන්තය භාවිතා කරමින් සිටියෙමි.
ස්කොටිසියස්

43
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
'ආපසු ශුන්‍යය' සිට 'විසි කිරීම IOException' දක්වා වෙනස් කිරීමට මම නිදහස ලබා ඇත්තෙමි
kritzikratzi

3
බයිට්ආරේ ඕට්පුට්ස්ට්රීම් # සමීප () කිසිවක් නොකරන නිසා සම්පත් සමඟ උත්සාහ කිරීම මෙහි අවශ්‍ය නොවේ. (ByteArrayOutputStream # flush () අවශ්‍ය නොවන අතර එයද කිසිවක් නොකරයි.)
ලූක් හචිසන්

29

ආරක්ෂිත විසඳුම (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සඳහා මෙහි බලන්න .

  • පරිමාණ අනුවාදය (ජාවා 9+ ප්‍රවේශ කළ නොහැකි විට):

    def readAllBytes(inputStream: InputStream): Array[Byte] =
      Stream.continually(inputStream.read).takeWhile(_ != -1).map(_.toByte).toArray

ඔබට බෆරය සහ බයිට් අරාව යන දෙකම ඇති බැවින් යම් අවස්ථාවක දී ඔබ භාවිතා කළ මතකය දෙගුණයක් වනු ඇතැයි මින් අදහස් නොවේ ද? නිමැවුම් බයිට් අරා වෙත කෙලින්ම බයිට් යැවීමට ක්‍රමයක් නැද්ද?
ඇන්ඩ්‍රොයිඩ් සංවර්ධක

@androiddeveloper; මට කණගාටුයි. මම පිළිතුර දන්නේ නැහැ! නමුත් මම හිතන්නේ නැහැ. මම හිතන්නේ මේ ආකාරයෙන් (බෆරය භාවිතා කිරීම) ප්‍රශස්ත ක්‍රමයක්.
මිර්-ඉස්මයිලි

මම පරීක්ෂා කර බැලූ විට එය සිදු වේ, නමුත් ඔබ ප්‍රමාණය නොදන්නා විට ඔබට තෝරා ගත හැකි එකම විසඳුම එය බව පෙනේ. ඔබ දැනටමත් ප්‍රමාණය දන්නේ නම්, ඔබට ලබා දී ඇති ප්‍රමාණය සමඟ බයිට්-අරාව කෙලින්ම සාදා එය පුරවන්න. එබැවින්, ඔබ බයිට් ප්‍රමාණයේ පරාමිතියක් ලබා ගන්නා ශ්‍රිතයක් භාවිතා කරන අතර එය වලංගු නම්, වෙනත් විශාල වස්තුවක් නිර්මාණය නොකර බයිට් අරාව කෙලින්ම නිර්මාණය කර පිරවීම සඳහා එය භාවිතා කරන්න.
ඇන්ඩ්‍රොයිඩ් සංවර්ධක

@androiddeveloper; ඔබේ තොරතුරු වලට ස්තූතියි. මම ඔවුන්ව දැනගෙන හිටියේ නැහැ.
මිර්-ඉස්මයිලි

19

ඔබට ඇත්ත වශයෙන්ම රූපය byte[]අවශ්‍යද? byte[]රූප ගොනුවක සම්පූර්ණ අන්තර්ගතය, රූප ගොනුවේ ඇති ඕනෑම ආකෘතියකින් කේතනය කර ඇති හෝ RGB පික්සල් අගයන්ගෙන් ඔබ හරියටම අපේක්ෂා කරන්නේ කුමක්ද?

මෙහි ඇති වෙනත් පිළිතුරු මඟින් ගොනුවක් කියවිය යුතු ආකාරය පෙන්වයි byte[]. ඔබගේ byte[]ගොනුවේ නිශ්චිත අන්තර්ගතයන් අඩංගු වන අතර රූප දත්ත සමඟ ඕනෑම දෙයක් කිරීමට ඔබට එය විකේතනය කළ යුතුය.

පින්තූර කියවීම (සහ ලිවීම) සඳහා ජාවාහි සම්මත API යනු ImageIO API වන අතර එය ඔබට පැකේජයෙන් සොයාගත හැකිය 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

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

කියන්න, බයිට් අරා විශාල වුවහොත් එය ගොඩවල් සඳහා OOM වලට හේතු විය හැකිද? බයිට් ගබඩා කිරීම සඳහා ජේඑන්අයි භාවිතා කරන සමාන විසඳුමක් තිබේද, පසුව අපට එහි ගබඩා කර ඇති දත්ත වලින් (තාවකාලික හැඹිලියක්) ආදාන ප්‍රවාහය භාවිතා කළ හැකිද?
ඇන්ඩ්‍රොයිඩ් සංවර්ධක

14

ඔබට Apache commons-io පුස්තකාලය භාවිතා කිරීමට අවශ්‍ය නැතිනම්, මෙම ස්නිපටය ගනු ලබන්නේ sun.misc.IOUtils පන්තියෙනි. එය බයිට්බෆර් භාවිතා කරන පොදු ක්‍රියාවට වඩා දෙගුණයක් වේගවත් ය:

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 (ප්‍රතිදානය); (නමුත් මගේ පිළිතුර බලන්න)
ලූක් හචිසන්

said ලූක්-හචිසන් මම කී පරිදි, මෙය සූර්යයාගේ විසඳුමයි. වඩාත් සුලභ අවස්ථාවන්හිදී ඔබ ආදාන ප්‍රවාහයේ විශාලත්වය නොදන්නා බැවින් (දිග == -1) දිග = පූර්ණ සංඛ්‍යා. MAX_VALUE; අදාළ වේ. දී ඇති දිග ආදාන ප්‍රවාහයේ දිගට වඩා විශාල වුවද මෙම විසඳුම ක්‍රියාත්මක වේ.
ක්‍රිස්ටියන් ක්‍රාල්ජික්

@LukeHutchison ඔබ දිග දන්නේ නම් ඔබට පේළි කිහිපයකින් එය හැසිරවිය හැකිය. ඔබ එක් එක් පිළිතුර දෙස බැලුවහොත්, දිග නොදන්නා බවට සියලු දෙනා මැසිවිලි නගති. අවසාන වශයෙන් සම්මත පිළිතුරක් ජාවා 7 ඇන්ඩ්‍රොයිඩ් සමඟ භාවිතා කළ හැකි අතර බාහිර පුස්තකාලයක් අවශ්‍ය නොවේ.
සීසා ටොත්

12
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();

9

D ඇඩම්ස්කි: ඔබට බෆරය සම්පූර්ණයෙන්ම වළක්වා ගත හැකිය.

කේතය 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
ප්‍රමාණය කලින් දැන ගැනීම මත රඳා පවතී.
stolsvik

2
ඇත්ත වශයෙන්ම, නමුත් ඔවුන් ප්‍රමාණය දැන සිටිය යුතුය: "මට රූපයක් කියවීමට අවශ්‍යයි"
pihentagy

1
ඔබ ප්‍රමාණය දන්නේ නම්, ජාවා ඔබට කේතය සපයයි. "DataInputStream" සඳහා මගේ පිළිතුර හෝ ගූගල් බලන්න, එය කියවීමේ සම්පූර්ණ ක්‍රමයයි.
ඩර්මොරිට්ස්

එම ව්‍යතිරේකය විසි කළ හොත් ඔබ වසා දැමිය යුතු 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();

කෙසේ වෙතත්, සාමාන්‍යයෙන් මෙහෙයුම් පද්ධතිය දැනටමත් ප්‍රමාණවත් තරම් බෆර් කර ඇති අතර කුඩා ලිපිගොනු සඳහා විශාල කරදරයක් නොවනු ඇත. දෘ disk තැටි හිස සෑම බයිටයක්ම වෙන වෙනම කියවනවා සේ නොවේ (දෘ disk තැටිය යනු චුම්බක කේතගත තොරතුරු සහිත හැරවුම් වීදුරු තහඩුවකි, දත්ත සුරැකීම සඳහා අප භාවිතා කරන අමුතු නිරූපකය වැනි ය: P).
මාර්ටන් බොඩෙව්ස්

7
Ar මාර්ටන් බොඩ්වේස්: බොහෝ උපාංගවල එක්තරා ආකාරයක බ්ලොක් හුවමාරුවක් ඇත, එබැවින් සෑම කියවීමක්ම () සත්‍ය උපාංග ප්‍රවේශයක් ඇති නොකරයි, ඇත්ත වශයෙන්ම, නමුත් බයිටයකට OS ඇමතුමක් තිබීම දැනටමත් කාර්ය සාධනය විනාශ කිරීමට ප්‍රමාණවත් වේ. මෙම ඔතන අතර InputStreamදී BufferedInputStreamබව කේතය පෙර කේතය තවත් එක් ආරක්ෂණය අනවශ්ය අත්පොත පිටපත් වැඩ කරන්නේ බව, මෙම මෙහෙයුම් පද්ධතිය-ඇමතුම් අඩු කිරීමට සහ සැලකිය යුතු කාර්ය සාධනය අවාසි අවම වනු ඇත.
හොල්ගර්


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
ඔබ උත්සාහ කළ හැකි සම්පත් භාවිතා කළ යුතුය.
වික්ටර් ස්ටෆූසා

දෝෂයක් ඇති වුවහොත් අවසානයේදී ඔබේ වැඩ කටයුතු අවසන් කිරීම අවශ්‍ය වේ, එසේ නොමැතිනම් මෙය මතක කාන්දු වීමකට හේතු විය හැක.
එම්.ජී.ඩේවිස්

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>);
    }
}

සටහන මෙම විසඳුම දමනවා බව carriage return ( '\ r') සහ නුසුදුසු විය හැක.


4
ඒ සඳහා ය String. OP ඉල්ලයි byte[].
ශීත කළ ෆයර්

එය \rගැටලුවක් විය හැකි පමණක් නොවේ. මෙම ක්‍රමය මඟින් බයිට් අක්ෂර බවට පරිවර්තනය කර නැවත නැවතත් (InputStreamReader සඳහා පෙරනිමි අක්‍ෂර කට්ටලය භාවිතා කරමින්). පෙරනිමි අක්ෂර කේතීකරණයේ වලංගු නොවන ඕනෑම බයිට් (ලිනක්ස් හි UTF-8 සඳහා -1 යැයි කියනු ලැබේ) දූෂිත වනු ඇත, බයිට් ගණන පවා වෙනස් කළ හැකිය.
seanf

මෙය හොඳ පිළිතුරක් සේ පෙනේ, නමුත් පෙළ නැඹුරු. ගැනුම්කරු පරෙස්සම් වන්න.
වීසීල්

1

මම කුණු කසළ දත්ත ලිවීම සඳහා නිවැරදි කිරීමක් සමඟ @ නුමන්ගේ පිළිතුර සංස්කරණය කිරීමට උත්සාහ කළ නමුත් සංස්කරණය ප්‍රතික්ෂේප විය. මෙම කෙටි කේත කොටස දීප්තිමත් කිසිවක් නොවූවත් මට වෙනත් හොඳ පිළිතුරක් දැකිය නොහැක. මෙන්න මට වඩාත්ම අර්ථවත් වන්නේ:

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 ByteArrayOutputStream වසා දැමිය යුතු නැත. කියවීමේ හැකියාව සඳහා අතහැර දමා ඇති උත්සාහයන් / අවසානයේ ඉදිකිරීම්


1

InputStream.available()ප්‍රලේඛනය බලන්න :

කන්ටේනරයක ප්‍රමාණයට ඔබ මෙම ක්‍රමය භාවිතා නොකළ යුතු බව වටහා ගැනීම විශේෂයෙන් වැදගත් වන අතර කන්ටේනරයේ ප්‍රමාණය වෙනස් කිරීමකින් තොරව ඔබට මුළු ධාරාවම කියවිය හැකි යැයි උපකල්පනය කරන්න. එවැනි අමතන්නන් බොහෝ විට තමන් කියවන සෑම දෙයක්ම බයිට්ආරේ ඕට්පුට්ස්ට්රීම් වෙත ලියා එය බයිට් අරාවකට පරිවර්තනය කළ යුතුය. විකල්පයක් ලෙස, ඔබ ගොනුවකින් කියවන්නේ නම්, File.length ගොනුවේ වත්මන් දිග නැවත ලබා දෙයි (ගොනුවේ දිග වෙනස් කළ නොහැකි යැයි උපකල්පනය කළත් වැරදියි, ගොනුවක් කියවීම සහජයෙන්ම විචක්ෂණශීලී වේ).


1

කිසියම් හේතුවක් නිසා එය මේසයෙන් ඉවතට ඇත්නම් එය ඩේටා ඉන්පුට්ස්ට්රීම් එකක ඔතා තබන්න, එය ඔබට -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

S3 වස්තුව බයිට්ආරේ බවට පරිවර්තනය කරන අතරම AWS ගනුදෙනු කිහිපයක් සඳහා යම් ප්‍රමාදයක් අපට පෙනේ.

සටහන: S3 වස්තුව PDF ලේඛනයකි (උපරිම ප්‍රමාණය 3 mb).

S3 වස්තුව බයිට්ආරේ බවට පරිවර්තනය කිරීම සඳහා අපි # 1 (org.apache.commons.io.IOUtils) විකල්පය භාවිතා කරමු. එස් 3 වස්තුව බයිට්ආරේ බවට පරිවර්තනය කිරීම සඳහා එස් 3 ඉන්බිල්ඩ් අයිඕටිල්ස් ක්‍රමය සපයන බව අපි දැක ඇත්තෙමු, ප්‍රමාදය වළක්වා ගැනීම සඳහා එස් 3 වස්තුව බයිට්ආරේ වෙත පරිවර්තනය කිරීමට හොඳම ක්‍රමය කුමක්දැයි තහවුරු කරන ලෙස අපි ඔබෙන් ඉල්ලා සිටිමු.

විකල්ප 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
වර්තමාන ගැටළුව විසඳීම සඳහා මෙම පිළිතුර OP ට උපකාර කරන්නේ කෙසේද යන්නට පිළිතුරක් සමඟ පැහැදිලි කිරීමක් එක් කරන්න
Jan 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
මෙම කේත ස්නිපටය මඟින් ප්‍රශ්නය විසඳිය හැකි අතර, පැහැදිලි කිරීමක් ඇතුළුව ඔබේ තනතුරේ ගුණාත්මකභාවය වැඩි දියුණු කිරීමට උපකාරී වේ. අනාගතයේ දී ඔබ පා readers කයන් සඳහා වන ප්‍රශ්නයට පිළිතුරු සපයන බව මතක තබා ගන්න, ඔබේ කේත යෝජනාවට හේතු එම පුද්ගලයින් නොදැන සිටිය හැකිය.
ෆෙරිබිග්

0

ජාවා 7 සහ පසුව:

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

21
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
        }
    }

ඔබ ප්‍රමාණය දන්නේ නම්, අනෙක් විසඳුම් හා සසඳන විට භාවිතා කළ මතකය දෙගුණයක් කිරීමෙන් එය ඉතිරි වේ (කෙටි මොහොතකින්, නමුත් තවමත් ප්‍රයෝජනවත් විය හැකිය). එයට හේතුව ඔබ මුළු ධාරාවම අවසානය දක්වා කියවිය යුතු අතර පසුව එය බයිට් අරාවකට පරිවර්තනය කළ යුතුය (ඔබ අරාව ලැයිස්තුවකට සමාන අරාව ලැයිස්තුවකට සමානයි).

ඉතින්, ඔබ ඇන්ඩ්‍රොයිඩ් හි සිටී නම්, ඔබට හැසිරවීමට යූරි ටිකක් තිබේ නම්, ඔබට මෙය භාවිතා කර ප්‍රමාණය ලබා ගැනීමට උත්සාහ කළ හැකිය:

    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
    }

0

නැවත භාවිතා කළ හැකි වස්තු-නැඹුරු ජාවා සංරචක සමඟ ඔබට පතොක් පුස්තකාලය භාවිතා කළ හැකිය . OOP මෙම පුස්තකාලය මගින් අවධාරණය කරනු ලැබේ, එබැවින් ස්ථිතික ක්‍රම, NULL සහ යනාදිය සැබෑ වස්තූන් සහ ඒවායේ ගිවිසුම් (අතුරුමුහුණත්) පමණි. InputStream කියවීම වැනි සරල මෙහෙයුමක් ඒ ආකාරයෙන් කළ හැකිය

final InputStream input = ...;
final Bytes bytes = new BytesOf(input);
final byte[] array = bytes.asBytes();
Assert.assertArrayEquals(
    array,
    new byte[]{65, 66, 67}
);

Bytesදත්ත ව්‍යුහය සමඟ වැඩ කිරීම සඳහා විශේෂිත වර්ගයක් තිබීම, byte[]අත ළඟ ඇති කාර්යයන් විසඳීම සඳහා OOP උපක්‍රම භාවිතා කිරීමට අපට හැකියාව ලබා දෙයි. කාර්ය පටිපාටික “උපයෝගීතා” ක්‍රමයක් අපට කිරීමට තහනම් කරයි. උදාහරණයක් ලෙස, ඔබ මෙයින් කියවා ඇති බයිට් 64 බේස් 64 වෙත යොමු කළ යුතුය InputStream. මෙම අවස්ථාවේදී ඔබ සැරසිලි රටාව භාවිතා කරන අතර Base64 සඳහා ක්‍රියාත්මක කිරීමේදී බයිට් වස්තුව ඔතා. පතොක් දැනටමත් එවැනි ක්‍රියාත්මක කිරීමක් සපයයි:

final Bytes encoded = new BytesBase64(
    new BytesOf(
        new InputStreamOf("XYZ")
    )
);
Assert.assertEquals(new TextOf(encoded).asString(), "WFla");

සැරසිලි රටාව භාවිතා කිරීමෙන් ඔබට ඒවා එකම ආකාරයකින් විකේතනය කළ හැකිය

final Bytes decoded = new Base64Bytes(
    new BytesBase64(
        new BytesOf(
            new InputStreamOf("XYZ")
        )
    )
);
Assert.assertEquals(new TextOf(decoded).asString(), "XYZ");

ඔබගේ කර්තව්‍යය කුමක් වුවත් Bytesඑය විසඳීම සඳහා ඔබටම ක්‍රියාත්මක කළ හැකිය .

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.