2012-07-31 12 views
6

Ich brauche die Größe in Bytes eines InputStream, ohne eine Datei-Instanz zu erstellen. Gibt es eine Möglichkeit, dies mit Java NIO zu tun?Java InputStream Größe

+2

Warum Sie diese brauchen würde? – Jeffrey

+3

Der Vertrag von 'InputStream' sagt nichts in Bezug darauf, dass es endlich sein soll. – oldrinb

+1

Oder in Bezug auf seine im Voraus definiert werden. – EJP

Antwort

24

Von einem allgemeinen InputStream? Sie müssten einfach weiterlesen und lesen (z. B. in denselben Puffer, immer und immer wieder) und dabei zählen, wie viele Bytes Sie gelesen haben, bis Sie das Ende des Streams erreicht haben.

Natürlich werden Sie dann nicht in der Lage sein, die Daten selbst zu lesen ... wenn Sie das tun wollen, müssen Sie die Daten so aufbewahren, wie Sie sie lesen, z. indem Sie es in eine ByteArrayOutputStream kopieren.

(Wenn Sie in der Lage sind, die Daten zur gleichen Zeit wie die Länge zu verarbeiten, tun Sie das - wie Sie es mit einer Schleife lesen, jedes Mal in den gleichen Puffer lesen, erhöhen Sie einfach einen Zähler zum Aufzeichnen ., wie viel Sie gelesen haben Sie haben nicht wirklich gab uns keine Informationen darüber, was Sie mit dem Strom tun wollen)

+1

Oder kopieren Sie es einfach an das Ziel, während Sie gehen, eliminieren Sie die Zählung, und den ByteArrayOutputStream, und die Latenz und den Raum verschwendet, indem Sie alles in den Speicher bereit. – EJP

+0

@EJP: Das hängt davon ab, was du danach machen wirst. Möglicherweise kopieren Sie es nicht an ein Ziel. –

+0

Also lesen Sie es einfach und verarbeiten Sie es währenddessen. Ich bin sehr misstrauisch gegenüber "Lösungen", die damit beginnen, die gesamte Eingabe zu lesen, es sei denn, es ist bekannt, dass die Eingabe sehr klein ist. In diesem Fall müssen Sie kaum wissen, welche Größe es überhaupt ist, oder? – EJP

1

Ein paar zusätzliche Optionen.

Je nach blockiert Natur der Eingabestrom können Sie available() im Stream aufrufen.

Wenn die Streams kleiner sind, könnten Sie sie in PushbackInputStream s schreiben, die Bytes zählen und dann zurückspulen.

+1

-1 verwenden. available() gibt * not * die Größe eines Streams zurück und es gibt eine spezielle Warnung im Javadoc, die das sagt. Und * alle * Eingabestreams blockieren. – EJP

+6

Muss widersprechen. Überprüfen Sie das JavaDoc. http://docs.oracle.com/javase/6/docs/api/java/io/FileInputStream.html#available%28%29. Der Rückgabewert von available() gibt an, dass es sich um die Anzahl der Bytes handelt, die ohne ** Blockierung gelesen werden können. Außerdem "In einigen Fällen scheint ein nicht blockierendes Lesen (oder Überspringen) blockiert zu sein, wenn es nur langsam ist, zum Beispiel beim Lesen großer Dateien über langsame Netzwerke". Und im Fall von FileInputStreams ist es häufig ein zuverlässiger Indikator für die Größe. – Nicholas

+2

Genau das habe ich gesagt. Es ist genau das Gegenteil von dem, was du gesagt hast.Sie haben angegeben, dass available() verwendet werden kann, um die Größe des Eingabestreams zurückzugeben, was das Thema dieser Frage ist. Das ist nicht dasselbe wie die Anzahl der Bytes, die ohne Blockierung gelesen werden können. Betrachten Sie einen Sockel. Der Teil nach "weiter" hat keine offensichtliche Relevanz. Es gibt einen anderen Satz, den Sie nicht zitiert haben, der ausdrücklich vor der Verwendung in Ihrem letzten Satz warnt, und es gibt nichts in der Frage über FileInputStream. – EJP

6

Es ist im Prinzip nicht bekannt (denke an einen Peer, der niemals aufhört zu schreiben), und du brauchst es nicht. Lesen und schreiben Sie in einer Schleife mit einem Puffer fester Größe. NIO bietet keine magische Lösung.

-2

können Sie die Größe des Input mit getBytes (input) von Utils.java überprüfen erhalten folgenden Link,

Get Bytes from Inputstream

+0

Mit anderen Worten lesen Sie einfach den Stream bis zum Ende des Streams, oder verlassen Sie sich auf undokumentierte Eigenschaften von ByteArrayInputStream. Eine sehr schlechte Qualität Verbindung, und es verwendet NIO nicht, die in der Frage spezifiziert wurde. -1 – EJP