2010-05-06 10 views

Répondre

17

Si c'est un fichier texte, et que vous voulez vous limiter à Scala et Java, puis en utilisant scala.io.Source pour faire la lecture est probablement le fastest-- il n'est pas construit, mais facile à écrire:

def inputToFile(is: java.io.InputStream, f: java.io.File) { 
    val in = scala.io.Source.fromInputStream(is) 
    val out = new java.io.PrintWriter(f) 
    try { in.getLines().foreach(out.println(_)) } 
    finally { out.close } 
} 

mais si vous avez besoin d'autres bibliothèques de toute façon, vous pouvez vous rendre la vie encore plus facile en les utilisant (comme Michel illustre).

(PS - Scala 2.7, getLines ne devrait pas avoir un () après.)

(PPS - dans les anciennes versions de Scala, getLines n'a pas enlevé la nouvelle ligne, donc vous devez print au lieu de . println)

+0

ce code perd les caractères de nouvelle ligne. – shinichy

+0

@shinichy - Le comportement a changé depuis que j'ai écrit la réponse. Je l'ai mis à jour. –

+0

Merci pour la mise à jour! – shinichy

7

Je ne connais aucune API spécifique à Scala, mais comme Scala est entièrement compatible avec Java, vous pouvez utiliser n'importe quelle autre bibliothèque comme Apache Commons IO et Apache Commons FileUpload.

Voici quelques exemples de code (non testé):

//using Commons IO: 
val is = ... //input stream you want to write to a file 
val os = new FileOutputStream("out.txt") 
org.apache.commons.io.IOUtils.copy(is, os) 
os.close() 

//using Commons FileUpload 
import javax.servlet.http.HttpServletRequest 
import org.apache.commons.fileupload.{FileItemFactory, FileItem} 
import apache.commons.fileupload.disk.DiskFileItemFactory 
import org.apache.commons.fileupload.servlet.ServletFileUpload 
val request: HttpServletRequest = ... //your HTTP request 
val factory: FileItemFactory = new DiskFileItemFactory() 
val upload = new ServletFileUpload(factory) 
val items = upload.parseRequest(request).asInstanceOf[java.util.List[FileItem]] 
for (item <- items) item.write(new File(item.getName)) 
25

Avec Java 7, vous pouvez utiliser Filesfrom the new File I/O:

Files.copy(from, to) 

from et to peut être Path s ou InputStream s. De cette façon, vous pouvez même l'utiliser pour extraire facilement des ressources d'applications contenues dans un pot.

+0

Avez-vous besoin d'appeler 'close' après cela? – Jus12

+0

'Files' lui-même ne représente pas un fichier, mais est une collection statique de fonctions d'E/S, il n'a donc pas besoin d'être fermé. 'Files.copy' ne manipule pas les flux que vous transmettez, donc tout ce dont vous avez besoin de fermer, vous devez vous fermer. – notan3xit

1

La méthode inputToFile donnée ci-dessus ne fonctionne pas bien avec les fichiers binaires tels que les fichiers .pdf. Il lance une exception d'exécution lors de la tentative de décodage du fichier en chaîne. Ce qui a fonctionné pour moi était ceci:

def inputStreamToFile(inputStream: java.io.InputStream, file: java.io.File) = { 
    val fos = new java.io.FileOutputStream(file) 
    fos.write(
     Stream.continually(inputStream.read).takeWhile(-1 !=).map(_.toByte).toArray 
    ) 
    fos.close() 
}