2010-11-30 17 views
61

J'ai une méthode qui attend que celle de la variable d'entrée soit de type java.io.File mais ce que je reçois est seulement InputStream. Je ne peux pas changer la signature de la méthode. Comment est-ce que je peux convertir le InputStream dans le type de Fichier sans réellement écrire le dossier sur le système de fichiers?.Comment convertir InputStream en fichier virtuel

+0

Est-ce une fonction intégrée? ou est-ce une fonction personnalisée? –

+2

@Richard: * "Je ne peux pas changer la signature de la méthode." * – BalusC

+0

Pourquoi avez-vous exactement besoin d'un objet 'File' au lieu de InputStream? – Poindexter

Répondre

98

Quelque chose comme ça devrait fonctionner. Notez que pour simplifier, j'ai utilisé une fonctionnalité Java 7 (essayez le bloc avec une ressource pouvant être fermée), et IOUtils depuis Apache commons-io. Si vous ne pouvez pas utiliser ceux-ci, ce sera un peu plus long, mais la même idée.

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

Est-ce que createTempFile n'écrit pas réellement un vrai fichier, que vous pouvez voir dans le système de fichiers? –

+0

vous êtes techniquement correct. en utilisant le code ci-dessus, le fichier temporaire existera jusqu'à ce que le programme se termine ou il est supprimé par le programme. – cobbzilla

+0

Les docs de deleteOnExit disent que vous ne devriez pas compter dessus pour fonctionner (et je pense que ça ne fait même rien): http://developer.android.com/reference/java/io/File.html#deleteOnExit(). En outre, si vous savez comment diffuser l'audio en lecture, sans aucun fichier, s'il vous plaît écrivez à ce sujet ici: http://stackoverflow.com/q/36552381/878126 –

27

Vous ne pouvez pas. Le flux d'entrée est juste un flux générique de données et il n'y a aucune garantie qu'il provient réellement d'un fichier. Si quelqu'un créait un InputStream à partir de la lecture d'un service Web ou venait de convertir un String en InputStream, il n'y aurait aucun moyen de le lier à un fichier. Ainsi, la seule chose que vous pouvez faire est d'écrire des données du flux dans un fichier temporaire (par exemple en utilisant la méthode File.createTempFile) et de charger ce fichier dans votre méthode.

+6

En effet, le fichier ['File # createTempFile()'] (http://download.oracle.com/javase/6/docs/api/java/io/File .html # createTempFile% 28java.lang.String,% 20java.lang.String% 29) est vraiment votre meilleur pari. – BalusC

+6

Voir aussi ['Fichier # deleteOnExit()'] (http://download.oracle.com/javase/6/docs/api/java/io/File.html#deleteOnExit%28%29), ce qui provoque la JVM pour tenter de supprimer le fichier automatiquement lorsque la JVM se ferme. Bien sûr, il est préférable de supprimer le fichier temporaire manuellement et immédiatement, une fois que vous savez que le fichier n'est plus nécessaire et n'est plus utilisé. Mais dans un monde imparfait, des solutions parfois imparfaites sont nécessaires. –