2010-11-30 10 views
61

Tengo un método que espera que la variable de entrada sea de tipo java.io.File pero lo que obtengo es solo InputStream. No puedo cambiar la firma del método. ¿Cómo puedo convertir el InputStream en el tipo de archivo sin realmente escribir el archivo en el sistema de archivos ?.Cómo convertir InputStream al archivo virtual

+0

¿Esta función está incorporada? o es una función personalizada? –

+2

@Richard: * "No puedo cambiar la firma del método." * – BalusC

+0

¿Por qué exactamente necesita un objeto 'Archivo' en lugar de InputStream? – Poindexter

Respuesta

98

Algo así debería funcionar. Tenga en cuenta que, para mayor simplicidad, he utilizado una característica de Java 7 (bloque de prueba con recurso de cierre) e IOUtils de Apache commons-io. Si no puedes usarlos, será un poco más largo, pero la misma idea.

import org.apache.commons.io.IOUtils; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 

public class StreamUtil { 

    public static final String PREFIX = "stream2file"; 
    public static final String SUFFIX = ".tmp"; 

    public static File stream2file (InputStream in) throws IOException { 
     final File tempFile = File.createTempFile(PREFIX, SUFFIX); 
     tempFile.deleteOnExit(); 
     try (FileOutputStream out = new FileOutputStream(tempFile)) { 
      IOUtils.copy(in, out); 
     } 
     return tempFile; 
    } 

} 
+6

¿No es createTempFile realmente escribe un archivo real, que se puede ver en el sistema de archivos? –

+0

eres técnicamente correcto. utilizando el código anterior, el archivo temporal existirá hasta que el programa salga o el programa lo elimine. – cobbzilla

+0

Los documentos de deleteOnExit dicen que no debes confiar en que funcione (y creo que en realidad ni siquiera hace nada): http://developer.android.com/reference/java/io/File.html#deleteOnExit(). Además, si sabe cómo reproducir el audio en la reproducción, sin ningún archivo, escriba al respecto aquí: http://stackoverflow.com/q/36552381/878126 –

27

No puede. La secuencia de entrada es solo una secuencia genérica de datos y no hay garantía de que realmente se origine en un archivo. Si alguien creaba un InputStream leyendo un servicio web o simplemente convertía un String en un InputStream, no habría forma de vincularlo a un archivo. Entonces, lo único que puede hacer es escribir datos de la transmisión en un archivo temporal (por ejemplo, utilizando el método File.createTempFile) y alimentar este archivo en su método.

+6

De hecho, el ['File # createTempFile()'] (http://download.oracle.com/javase/6/docs/api/java/io/File .html # createTempFile% 28java.lang.String,% 20java.lang.String% 29) es realmente su mejor opción. – BalusC

+6

También vea ['File # deleteOnExit()'] (http://download.oracle.com/javase/6/docs/api/java/io/File.html#deleteOnExit%28%29), que causa la JVM para intentar eliminar el archivo automáticamente cuando sale la JVM. Por supuesto, es mejor eliminar el archivo temporal de forma manual e inmediata, una vez que sepa que el archivo ya no se necesita y ya no se usa. Pero en un mundo imperfecto a veces las soluciones imperfectas son necesarias. –

Cuestiones relacionadas