Bestimmen Sie die Größe eines InputStream

Lesezeit: 7 Minuten

Benutzer-Avatar
ChronoXIII

Meine aktuelle Situation ist: Ich muss eine Datei lesen und den Inhalt einfügen InputStream. Danach muss ich den Inhalt der platzieren InputStream in ein Byte-Array, das (soweit ich weiß) die Größe der benötigt InputStream. Irgendwelche Ideen?

Wie gewünscht, zeige ich den Eingabestream, den ich aus einer hochgeladenen Datei erstelle

InputStream uploadedStream = null;
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
java.util.List items = upload.parseRequest(request);      
java.util.Iterator iter = items.iterator();

while (iter.hasNext()) {
    FileItem item = (FileItem) iter.next();
    if (!item.isFormField()) {
        uploadedStream = item.getInputStream();
        //CHANGE uploadedStreambyte = item.get()
    }
}

Der Antrag ist a HttpServletRequest Objekt, das wie die ist FileItemFactory und ServletFileUpload stammt aus dem Apache Commons FileUpload-Paket.

Benutzer-Avatar
WB Schilf

Dies ist ein WIRKLICH alter Thread, aber er war immer noch das erste, was auftauchte, als ich das Problem googelte. Deshalb wollte ich nur noch ergänzen:

InputStream inputStream = conn.getInputStream();
int length = inputStream.available();

Hat für mich funktioniert. Und VIEL einfacher als die anderen Antworten hier.

Warnung Diese Lösung liefert keine zuverlässigen Ergebnisse bezüglich der Gesamtgröße eines Streams. Außer aus dem JavaDoc:

Beachten Sie, dass einige Implementierungen von {@code InputStream} zwar * die Gesamtzahl der Bytes im Stream zurückgeben, viele jedoch nicht.

  • Ich glaube nicht, dass das stimmt. Aus den Javadocs: „Beachten Sie, dass einige Implementierungen von InputStream zwar die Gesamtzahl der Bytes im Stream zurückgeben, viele jedoch nicht. Es ist niemals korrekt, den Rückgabewert dieser Methode zu verwenden, um einen Puffer zuzuweisen, der alle Daten darin enthalten soll Strom.” Es hat also möglicherweise auf Ihrer VM funktioniert, aber möglicherweise nicht auf der eines anderen. docs.oracle.com/javase/7/docs/api/java/io/…

    – Marvo

    17. Dezember 2013 um 0:23 Uhr


  • Ach psych. Schöner Fang! Ich denke, dieser Trick ist nicht gut für Code, der portabel sein muss. Ich habe es für ein Schulprojekt verwendet, also hat es für mich funktioniert. Danke aber, gut zu wissen für die Zukunft!

    – WB Schilf

    17. Dezember 2013 um 17:22 Uhr

  • Das ist perfekt, wenn Sie alle Daten wie in einem ByteArrayInputStream im Speicher haben.

    – Stapler

    15. April 2014 um 15:39 Uhr

  • Es ist falsch! Als die Dokumentation sagte über die available() method “Beachten Sie, dass einige Implementierungen von InputStream zwar die Gesamtzahl der Bytes im Stream zurückgeben, viele jedoch nicht. Es ist niemals korrekt, den Rückgabewert dieser Methode zu verwenden, um einen Puffer zuzuweisen, der alle Daten in diesem Stream enthalten soll.”

    – GVillani82

    18. März 2015 um 9:36 Uhr


  • Die Antwort ist irreführend, was ist mit Android-Dokumentewird deutlich gesagt: “Beachten Sie das diese Methode bietet eine so schwache Garantie das es ist in der Praxis nicht sehr nützlich“.

    – Xenia

    27. Januar 2016 um 17:34 Uhr

Benutzer-Avatar
Brian Agnew

Ich würde in a lesen ByteArrayOutputStream und dann anrufen toByteArray() um das resultierende Byte-Array zu erhalten. Sie müssen die Größe nicht im Voraus definieren (obwohl es sich möglicherweise um eine Optimierung handelt wenn du es weißt. In vielen Fällen werden Sie nicht)

  • Ich scheine festgestellt zu haben, dass Inputstream eine toString () -Methode hat, und dann kann ich einfach getBytes () aufrufen, um ein Byte-Array aus der Zeichenfolge zu erstellen. Ich frage mich, ob es irgendwelche Leistungsprobleme gibt, dies zu tun?

    – ChronoXIII

    13. Juli 2009 um 13:15 Uhr

  • Sie müssen bei Bytes/Zeichen-Konvertierungen vorsichtig sein. Ist das ursprünglich ein Bytestream? Wenn es Zeichen enthält, wie sind sie codiert usw. Wenn Sie diese über eine Netzwerkverbindung erhalten, würde ich vermuten, dass dies Ihr Hauptleistungsengpass ist, und ich würde mir keine Gedanken über den Konvertierungsaufwand machen

    – Brian Agnew

    13. Juli 2009 um 13:17 Uhr

  • Ich lese derzeit den Eingabestrom mit dem Bild als Binärstrom in eine Datenbank ein, dies scheint gut zu funktionieren, da ich die Datei danach wieder auslesen kann und es immer noch ein Bild ist

    – ChronoXIII

    13. Juli 2009 um 13:24 Uhr

  • Ja. Sie erhalten das vollständige Rohbyte-Array, keine Konvertierung, keine Probleme.

    – akarnokd

    13. Juli 2009 um 13:50 Uhr

  • Ist das nicht wirklich speicherineffizient, wenn Sie nur die Größe wollen?

    – cdmckay

    13. März 2013 um 20:47 Uhr

Sie können die Datenmenge in einem Stream nicht bestimmen, ohne ihn zu lesen; Sie können jedoch nach der Größe einer Datei fragen:

http://java.sun.com/javase/6/docs/api/java/io/File.html#length()

Wenn das nicht möglich ist, können Sie die gelesenen Bytes aus dem Eingabestream in a schreiben ByteArrayOutputStream die nach Bedarf wachsen.

  • In meinem Szenario enthält der Inputstream eine hochgeladene Datei aus einem HTML-Formular, ich kann die Dateigröße nicht abrufen, da ich die Datei nicht von der Festplatte lade.

    – ChronoXIII

    13. Juli 2009 um 13:12 Uhr

  • Wenn Ihr Eingabestrom mark() unterstützt, können Sie am Anfang markieren und ihn einfach vollständig durchlesen – dann reset() und mit der Verarbeitung beginnen.

    – akarnokd

    13. Juli 2009 um 13:14 Uhr

  • Die Datei ist ein Bild (möglicherweise groß), sodass das zweimalige Lesen des Streams zu Leistungsproblemen führen würde, nicht wahr?

    – ChronoXIII

    13. Juli 2009 um 13:16 Uhr

  • Versuch es. Wenn es sehr langsam ist, haben Sie Leistungsprobleme. Sonst nicht. So einfach ist das.

    – Bombe

    13. Juli 2009 um 13:19 Uhr

  • @ChronoXIII: Stimmt. Aus diesem Grund habe ich um ein kleines Codebeispiel gebeten, damit wir Ihr Szenario sehen können. Wenn sich Ihr Bild bereits im Speicher befindet (dank Dateiupload oder so), werden weitere Optionen geöffnet.

    – akarnokd

    13. Juli 2009 um 13:21 Uhr

Benutzer-Avatar
akarnokd

Ich wollte nur hinzufügen, dass Apache Commons IO Stream-Support-Dienstprogramme hat, um die Kopie durchzuführen. (Übrigens, was meinst du damit, die Datei in einen Inputstream zu platzieren? Kannst du uns deinen Code zeigen?)

Bearbeiten:

Okay, was möchten Sie mit dem Inhalt des Artikels machen? Da ist ein item.get() die zurückkehrt das Ganze in einem Byte-Array.

Bearbeiten2

item.getSize() wird das Hochgeladene zurückgeben Dateigröße.

Benutzer-Avatar
Amstegraf

Für InputStream

org.apache.commons.io.IoUtils.toByteArray(inputStream).length()

Für Optional

Stream.of(multipartFile.get()).mapToLong(file->file.getSize()).findFirst().getAsLong()

  • Ich kann IoUtils nirgendwo finden. Ich schätze du meinst org.apache.commons.io.IOUtils,

    – ostmond

    27. Juni 2019 um 8:49 Uhr

  • IOUtils.toByteArray(inputStream).length hat bei mir nicht funktioniert.

    – dev4life

    2. April 2020 um 16:21 Uhr

  • Ja. Es funktioniert nicht mit IOUtils. Ich bin mir nicht sicher, warum diese Methode ist und wie sie nützlich sein kann.

    – UM1979

    21. August 2020 um 4:02 Uhr

  • Es ist ein Byte-Array, das mit der Methode length() zurückgegeben wird. Ich habe nur vergessen, die Klammer hinzuzufügen

    – Amstegraf

    22. August 2020 um 10:26 Uhr


Benutzer-Avatar
Gnanam R

Sie können die Größe von InputStream mit getBytes (inputStream) von Utils.java abrufen. Überprüfen Sie diesen folgenden Link

Holen Sie sich Bytes von Inputstream

  • Ich kann IoUtils nirgendwo finden. Ich schätze du meinst org.apache.commons.io.IOUtils,

    – ostmond

    27. Juni 2019 um 8:49 Uhr

  • IOUtils.toByteArray(inputStream).length hat bei mir nicht funktioniert.

    – dev4life

    2. April 2020 um 16:21 Uhr

  • Ja. Es funktioniert nicht mit IOUtils. Ich bin mir nicht sicher, warum diese Methode ist und wie sie nützlich sein kann.

    – UM1979

    21. August 2020 um 4:02 Uhr

  • Es ist ein Byte-Array, das mit der Methode length() zurückgegeben wird. Ich habe nur vergessen, die Klammer hinzuzufügen

    – Amstegraf

    22. August 2020 um 10:26 Uhr


Benutzer-Avatar
Samuel

Die folgende Funktion sollte mit allen funktionieren InputStream. Wie andere Antworten angedeutet haben, können Sie die Länge eines nicht zuverlässig finden InputStream ohne es durchzulesen, aber im Gegensatz zu anderen Antworten, Sie sollte nicht Versuchen Sie, den gesamten Stream im Speicher zu halten, indem Sie in a einlesen ByteArrayOutputStream, und es gibt auch keinen Grund dazu. Anstatt den Stream zu lesen, sollten Sie sich idealerweise auf eine andere API für Streamgrößen verlassen, z. B. um die Größe einer Datei mit dem abzurufen File API.

public static int length(InputStream inputStream, int chunkSize) throws IOException {
    byte[] buffer = new byte[chunkSize];
    int chunkBytesRead = 0;
    int length = 0;
    while((chunkBytesRead = inputStream.read(buffer)) != -1) {
        length += chunkBytesRead;
    }
    return length;
}

Wählen Sie einen angemessenen Wert für chunkSize passend zur art InputStream. ZB beim Lesen von der Festplatte wäre es nicht effizient, einen zu kleinen Wert dafür zu haben chunkSize.

1283270cookie-checkBestimmen Sie die Größe eines InputStream

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy