Есть ли хороший, безопасный и быстрый способ записать InputStream в файл в Scala? - PullRequest
16 голосов
/ 06 мая 2010

В частности, я сохраняю загрузку файла в локальный файл в веб-приложении Lift.

Ответы [ 4 ]

31 голосов
/ 21 февраля 2013

С Java 7 вы можете использовать Files из нового File I / O :

Files.copy(from, to)

, где from и to могут быть Path с или InputStream с. Таким образом, вы даже можете использовать его для удобного извлечения ресурсов из приложений, упакованных в банку.

18 голосов
/ 06 мая 2010

Если это текстовый файл, и вы хотите ограничить себя Scala и Java, то использование scala.io.Source для чтения, вероятно, является самым быстрым - оно не встроено, но легко написать:

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

Но если вам все равно нужны другие библиотеки, вы можете сделать их жизнь еще проще, используя их (как показывает Мишель).

(P.S .-- в Scala 2.7, getLines не должно иметь () после него.)

(P.P.S .-- в старых версиях Scala, getLines не удалял символ новой строки, поэтому вам нужно print вместо println.)

8 голосов
/ 06 мая 2010

Я не знаю ни о каком специфическом для Scala API, но поскольку Scala полностью совместима с Java, вы можете использовать любую другую библиотеку, например Apache Commons IO и Apache Commons FileUpload .

Вот пример кода (не проверено):

//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))
1 голос
/ 08 октября 2014

Метод inputToFile, приведенный выше, плохо работает с двоичными файлами, такими как файлы .pdf. Выдает исключение времени выполнения при попытке декодировать файл в строку. Что сработало для меня, так это:

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