2009-07-13 18 views
39

Mi situación actual es: Tengo que leer un archivo y poner el contenido en InputStream. Después tengo que colocar el contenido del InputStream en una matriz de bytes que requiere (hasta donde sé) el tamaño de InputStream. ¿Algunas ideas?Determine el tamaño de un InputStream

a lo solicitado, que mostrará la secuencia de entrada que estoy creando a partir de un archivo cargado

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

La solicitud es un objeto HttpServletRequest, que es como el FileItemFactory y ServletFileUpload es desde el paquete de Apache Commons FileUpload.

Respuesta

10

Solo quería agregar, Apache Commons IO tiene utilidades de soporte de flujo para realiza la copia. (Por cierto, ¿qué quiere decir colocando el archivo en un InputStream ¿Nos puede mostrar su código??)

Editar:

bien, ¿qué es lo que quiere hacer con el contenido del artículo? Hay un item.get()which returns todo en una matriz de bytes.

Edit2

item.getSize() devolverá el file size subido.

+0

Actualmente guardo el archivo en un campo blob en la base de datos y lo envío como binarystream (entrada como un inputstream), ahora requiero el inputstream en una matriz de bytes ya que necesito hacer una firma de datos y la función solo toma matrices de bytes. – ChronoXIII

+1

item.get() te ordena la matriz de bytes, como mencioné. Y no se preocupe por el rendimiento de un tamaño a menos que esté trabajando con varias imágenes de MB. – akarnokd

+0

Ese podría ser el caso, ya que un usuario carga la imagen y parece que no puedo encontrar la forma de recortar automáticamente las imágenes en el lado del servidor. :( – ChronoXIII

16

No puede determinar la cantidad de datos en una secuencia sin leerla; puede, sin embargo, pregunte por el tamaño de un archivo:

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

Si eso no es posible, puede escribir los bytes se lee desde el flujo de entrada a un ByteArrayOutputStream que crecerá según se requiera.

+0

En mi escenario, el flujo de entrada contiene un archivo cargado desde un formulario HTML, no puedo obtener el tamaño del archivo ya que no soy de cargar el archivo del disco duro. – ChronoXIII

+1

Si su flujo de entrada tiene soporte mark(), puede marcar al principio y leerlo completamente, luego reiniciar() y comenzar a procesarlo. – akarnokd

+1

el archivo es una imagen (potencialmente grande) por lo que leer dos veces a través de la secuencia causaría problemas de rendimiento, ¿no? – ChronoXIII

24

Leería en un ByteArrayOutputStream y luego llamaría al toByteArray() para obtener la matriz de bytes resultante. No necesita definir el tamaño por adelantado (aunque posiblemente sea una optimización si lo sabe. En muchos casos no lo hará)

+0

Parece que encontré que inputstream tiene un método toString() y luego puedo llamar a getBytes() para crear una matriz de bytes fuera de la cadena. Me pregunto si hay problemas de rendimiento al hacer esto. – ChronoXIII

+0

Debe tener cuidado con las conversiones de bytes/caracteres. ¿Es esto originalmente un flujo de bytes? Si contiene caracteres, cómo están codificados, etc. Si los obtiene a través de una conexión de red, sospecho que ese es su cuello de botella de rendimiento principal y no me preocuparía por la sobrecarga de conversión. –

+0

Actualmente leo la corriente de entrada con la imagen en una base de datos como binarystream, esto parece funcionar bien, ya que puedo leer el archivo fuera de contraseñas y sigue siendo una imagen – ChronoXIII

3

puede obtener el tamaño de InputStream usando getBytes (InputStream) de Utils.java visite el siguiente enlace

Get Bytes from Inputstream

+0

¿No debería ser esto también una ¿respuesta correcta? ¿Algún problema con esta solución? – Arlyn

27

Es un tema muy viejo, pero aún así fue lo primero que debe aparecer cuando busqué en Google el problema. Así que solo quería agregar esto:

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

Funcionó para mí. Y MUCHO más simple que las otras respuestas aquí.

+38

No creo que sea exacto. Desde los Javadocs: "Tenga en cuenta que aunque algunas implementaciones de InputStream devolverán el número total de bytes en la secuencia, muchas no lo harán. Nunca es correcto usar el valor de retorno de este método para asignar un buffer destinado a contener todos los datos en este corriente." Por lo tanto, puede haber funcionado en su máquina virtual, pero podría no funcionar en la de otra persona. http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#available() – Marvo

+3

Oh psych. ¡Buena atrapada! Supongo que este truco no es bueno para el código que debe ser portátil. Estaba usando para un proyecto escolar, así que funcionó para mí. ¡Gracias sin embargo, bueno saberlo para el futuro! –

+4

Eso es perfecto cuando tienes todos los datos en la memoria como en un ByteArrayInputStream. – stacker

-1

utilizar este método, sólo hay que pasar el InputStream

public String readIt(InputStream is) { 
    if (is != null) { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8); 

     StringBuilder sb = new StringBuilder(); 
     String line; 
     while ((line = reader.readLine()) != null) { 
      sb.append(line).append("\n"); 
     } 
     is.close(); 
     return sb.toString(); 
    } 
    return "error: "; 
} 
+1

-1, esto supone que 'InputStream' siempre es una cadena (no es necesario porque puede tratarse de datos binarios) y, en cualquier caso, no devuelve el tamaño del flujo, que es lo que la pregunta solicitó. Además, agrega bytes adicionales ('\ n') a los datos, por lo que' sb.length() 'también será inexacto. –

+0

Ok, entiendo, así que esto es útil cuando sabes que esperas recibir una secuencia 'String'. '\ n' es realmente necesario porque tienes que dar algún formato a la entrada recibida, no quiero un chorizo ​​largo' String', por lo que incluso esos '\ n' cuentan. –

0

Cuando explícitamente se trata de un ByteArrayInputStream continuación, al contrario de algunos de los comentarios en esta página se puede utilizar la función .available() para obtener el tamaño. Solo tienes que hacerlo antes de que comiences a leer de él.

De los JavaDocs:

Devuelve el número de bytes restantes que se pueden leer (o saltan sobre ) de este flujo de entrada. El valor devuelto es count - pos, que es el número de bytes que quedan por leer del buffer de entrada.

https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayInputStream.html#available()

0
try { 
     InputStream connInputStream = connection.getInputStream(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    int size = connInputStream.available(); 

int disponible() Devuelve una estimación del número de bytes que puede ser leído (o pasó por alto) de este flujo de entrada sin bloquear por la siguiente invocación de un método para esta corriente de entrada. La siguiente invocación podría ser el mismo hilo u otro hilo. Una sola lectura u omisión de estos muchos bytes no bloqueará, pero puede leer u omitir menos bytes.

InputStream - Android SDK | Android Developers

Cuestiones relacionadas