Frage

Wie lese ich ein ganzes InputStream in ein Byte-Array?

War es hilfreich?

Lösung

Sie können die Apache verwenden Commons IO diese und ähnliche Aufgaben zu bewältigen.

Der IOUtils Typ hat eine statische Methode einen InputStream und gibt einen byte[] zu lesen.

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

Im Inneren entsteht ein ByteArrayOutputStream und kopiert die Bytes an den Ausgang, dann toByteArray() aufruft. Er verarbeitet große Dateien durch das Bytes in Blöcken von 4KiB kopiert werden.

Andere Tipps

Sie müssen jedes Byte von Ihrem InputStream lesen und es zu einem ByteArrayOutputStream schreiben. Anschließend können Sie das zugrunde liegende Byte-Array abrufen, indem toByteArray() Aufruf; z.

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

Schließlich, nach zwanzig Jahren gibt es eine einfache Lösung ohne die Notwendigkeit für eine 3rd-Party-Bibliothek, dank Java 9 :

InputStream is;
…
byte[] array = is.readAllBytes();

Beachten Sie auch die Bequemlichkeit Methoden readNBytes(byte[] b, int off, int len) und transferTo(OutputStream) wiederkehrenden Bedarf schaffen

Mit Vanille Java DataInputStream und seine readFully Methode (existiert seit mindestens Java 1.4):

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

Es gibt einige andere Aromen dieser Methode, aber ich benutze die ganze Zeit für diesen Anwendungsfall.

Wenn Sie geschehen google Guave verwenden, wird es so einfach sein wie:

byte[] bytes = ByteStreams.toByteArray(inputStream);

Wie immer auch Spring-Framework (Federkern seit 3.2.2) hat etwas für Sie: StreamUtils.copyToByteArray()

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

Brauchen Sie das Bild wirklich als? byte[]?Was genau erwarten Sie im byte[] - der komplette Inhalt einer Bilddatei, kodiert in welchem ​​Format auch immer die Bilddatei vorliegt, oder RGB-Pixelwerte?

Andere Antworten hier zeigen Ihnen, wie Sie eine Datei in eine einlesen byte[].Dein byte[] enthält den genauen Inhalt der Datei, und Sie müssten ihn dekodieren, um irgendetwas mit den Bilddaten zu tun.

Javas Standard-API zum Lesen (und Schreiben) von Bildern ist die ImageIO-API, die Sie im Paket finden javax.imageio.Sie können ein Bild aus einer Datei mit nur einer einzigen Codezeile einlesen:

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

Dadurch erhalten Sie eine BufferedImage, kein byte[].Um an die Bilddaten zu gelangen, können Sie anrufen getRaster() auf der BufferedImage.Dadurch erhalten Sie eine Raster Objekt, das über Methoden für den Zugriff auf die Pixeldaten verfügt (es verfügt über mehrere). getPixel() / getPixels() Methoden).

Suchen Sie in der API-Dokumentation nach javax.imageio.ImageIO, java.awt.image.BufferedImage, java.awt.image.Raster usw.

ImageIO unterstützt standardmäßig eine Reihe von Bildformaten:JPEG, PNG, BMP, WBMP und GIF.Es ist möglich, Unterstützung für weitere Formate hinzuzufügen (Sie benötigen ein Plug-in, das die ImageIO-Dienstanbieterschnittstelle implementiert).

Siehe auch das folgende Tutorial: Arbeiten mit Bildern

Wenn Sie nicht die Apache commons-io-Bibliothek verwenden möchten, wird dieser Ausschnitt aus der sun.misc.IOUtils Klasse genommen. Es ist fast doppelt so schnell wie die gemeinsame Umsetzung mit ByteBuffers:

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

In-Fall, dass jemand immer noch auf die Suche nach einer Lösung ohne Abhängigkeit und Wenn Sie eine Datei .

  

1) Datainputstream

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

2) ByteArrayOutputStream

 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) Random

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

Sicher Lösung (mit der Fähigkeit, close Ströme korrekt):

  • Java 9+ Version:

    final byte[] bytes;
    try (inputStream) {
        bytes = inputStream.readAllBytes();
    }
    
  • Java 8 Version:

    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);
            }
        }
    }
    
  • Kotlin Version (wenn Java 9+ nicht erreichbar ist):

    @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()
        }
    }
    

    Um zu vermeiden, verschachtelte use finden Sie unter hier .

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

@Adamski:. Sie können Puffer vermeiden vollständig

-Code kopiert von http://www.exampledepot.com/egs/java.io/File2ByteArray. html (Ja, es ist sehr ausführlich, aber die Hälfte der Größe des Speichers als die andere Lösung benötigt.)

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

Java 9 gibt Ihnen schließlich eine schöne Methode:

InputStream in = ...;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
in.transferTo( bos );
byte[] bytes = bos.toByteArray();

Ich weiß, es ist zu spät, aber hier denke ich, ist saubere Lösung, die besser lesbar ist ...

/**
 * 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();
}

Java 8 Art und Weise (dank BufferedReader und Adam Bien )

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

Hinweis , dass diese Lösung wischt Carriage Return ( '\ r') und ungeeignet sein kann.

habe ich versucht, mit einem Fix für das Schreiben von Datenmüll @ numan Antwort zu bearbeiten, sondern bearbeiten wurde abgelehnt. Während dieses kurze Stück Code ist brillant nichts kann ich keine andere bessere Antwort sehen. Hier ist, was am meisten Sinn macht für mich:

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 muss nicht geschlossen werden. try / finally-Konstrukte zur besseren Lesbarkeit weggelassen

Sehen Sie die InputStream.available() Dokumentation:

  

Es ist besonders wichtig zu erkennen, dass Sie nicht verwenden dürfen   Verfahren zur Größe eines Behälter und setzt voraus, dass die Gesamtheit lesen   des Stroms, ohne den Behälter zu ändern. Solche Anrufer   sollte wohl alles schreiben lesen sie auf eine ByteArrayOutputStream   und konvertieren, die auf ein Byte-Array. Alternativ, wenn Sie gerade lesen   aus einer Datei, kehrt file.length die aktuelle Länge der Datei   (Wenn auch unter der Annahme, die Länge der Datei kann nicht falsch sein kann sich ändern,   Lesen einer Datei ist von Natur aus rassig).

Java 7 und höher:

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

Der andere Fall korrekten Byte-Array über den Strom zu bekommen, nach Anforderung an dem Server senden und wartet auf die Antwort.

/**
         * 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);

Sie machen eine zusätzliche Kopie, wenn Sie ByteArrayOutputStream verwenden. Wenn Sie die Länge des Flusses kennen, bevor Sie es zu lesen beginnen (zB Input ist eigentlich ein Fileinputstream, und Sie können file.length () in der Datei aufrufen, oder die Input ist eine ZIP-Datei Eintrag Input, und Sie können ZipEntry nennen. length ()), dann ist es viel besser, direkt in die byte [] Array zu schreiben -. es die Hälfte der Speicher verwendet, und spart Zeit

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

N. B. die letzte Zeile oben behandelt Dateien abgeschnitten zu werden, während der Stream gelesen wird, wenn Sie diese Möglichkeit zu handhaben müssen, aber wenn die Datei bekommt mehr , während der Strom gelesen wird, wird der Inhalt im Byte [ ] Array wird nicht die neue Datei Inhalt enthalten werden verlängert, wird das Array einfach auf die alte Länge inputStreamLength abgeschnitten.

Ich benutze dies.

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

Das ist meine copy-paste-Version:

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

Wickeln Sie es in einem Datainputstream, wenn diese vom Tisch aus irgendeinem Grunde, nur lesen verwenden, um auf sie zu hämmern, bis es gibt Ihnen einen -1 oder den gesamten Block Sie gefragt.

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

Sie können versuchen, Cactoos :

byte[] array = new BytesOf(stream).bytes();

Wir sind eine gewisse Verzögerung für einige AWS Transaktion zu sehen, während der Konvertierung S3 Objekt ByteArray.

. Hinweis: S3 Objekt ist PDF-Dokument (max Größe 3 mb)

Wir sind mit der Option # 1 (org.apache.commons.io.IOUtils) das S3-Objekt ByteArray zu konvertieren. Wir haben bemerkt, S3 die inbuild IOUtils Verfahren bieten das S3-Objekt zu ByteArray konvertieren, wir bitten Sie, um zu bestätigen, was der beste Weg ist, um das S3-Objekt zu ByteArray konvertieren der Verzögerung zu vermeiden.

Option # 1:

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

Option # 2:

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

Auch lassen Sie mich wissen, wenn wir andere bessere Möglichkeit haben das s3 Objekt bytearray

zu konvertieren

Hier ist eine optimierte Version, die Daten zu vermeiden versucht, das Kopieren von so viel wie möglich Bytes:

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;
   }
}
/*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();
}

Dies funktioniert für mich,

if(inputStream != null){
                ByteArrayOutputStream contentStream = readSourceContent(inputStream);
                String stringContent = contentStream.toString();
                byte[] byteArr = encodeString(stringContent);
            }

readSourceContent ()

public static ByteArrayOutputStream readSourceContent(InputStream inputStream) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        int nextChar;
        try {
            while ((nextChar = inputStream.read()) != -1) {
                outputStream.write(nextChar);
            }
            outputStream.flush();
        } catch (IOException e) {
            throw new IOException("Exception occurred while reading content", e);
        }

        return outputStream;
    }

encodeString ()

public static byte[] encodeString(String content) throws UnsupportedEncodingException {
        byte[] bytes;
        try {
            bytes = content.getBytes();

        } catch (UnsupportedEncodingException e) {
            String msg = ENCODING + " is unsupported encoding type";
            log.error(msg,e);
            throw new UnsupportedEncodingException(msg, e);
        }
        return bytes;
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top