Scala: записать строку в файл одним оператором - PullRequest
133 голосов
/ 30 июля 2011

Для чтения файлов в Scala есть

Source.fromFile("file.txt").mkString

Существует ли эквивалентный и краткий способ записи строки в файл?

Большинство языков поддерживают что-то подобное. Мой любимый Groovy:

def f = new File("file.txt")
// Read
def s = f.text
// Write
f.text = "file contents"

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

Есть сообщения, похожие на это, но они не отвечают на мой точный вопрос или ориентированы на более старые версии Scala.

Например:

Ответы [ 13 ]

150 голосов
/ 28 мая 2014

Странно, что никто не предлагал операции NIO.2 (доступно начиная с Java 7):

import java.nio.file.{Paths, Files}
import java.nio.charset.StandardCharsets

Files.write(Paths.get("file.txt"), "file contents".getBytes(StandardCharsets.UTF_8))

Я думаю, что это, безусловно, самый простой, самый простой и самый идиоматический способ, и он не делаетнужны какие-то зависимости без самой Java.

79 голосов
/ 12 февраля 2013

Вот краткий однострочный текст с использованием refle.io.file, он работает с Scala 2.12:

reflect.io.File("filename").writeAll("hello world")

В качестве альтернативы, если вы хотите использовать библиотеки Java, вы можете сделать этот хак:

Some(new PrintWriter("filename")).foreach{p => p.write("hello world"); p.close}
66 голосов
/ 01 июня 2015

Краткая строка:

import java.io.PrintWriter
new PrintWriter("filename") { write("file contents"); close }
40 голосов
/ 30 июля 2011

Если вам нравится синтаксис Groovy, вы можете использовать шаблон проектирования Pimp-My-Library , чтобы перенести его в Scala:

import java.io._
import scala.io._

class RichFile( file: File ) {

  def text = Source.fromFile( file )(Codec.UTF8).mkString

  def text_=( s: String ) {
    val out = new PrintWriter( file , "UTF-8")
    try{ out.print( s ) }
    finally{ out.close }
  }
}

object RichFile {

  implicit def enrichFile( file: File ) = new RichFile( file )

}

Он будет работать должным образом:

scala> import RichFile.enrichFile
import RichFile.enrichFile

scala> val f = new File("/tmp/example.txt")
f: java.io.File = /tmp/example.txt

scala> f.text = "hello world"

scala> f.text
res1: String = 
"hello world
22 голосов
/ 08 февраля 2012
import sys.process._
"echo hello world" #> new java.io.File("/tmp/example.txt") !
12 голосов
/ 14 сентября 2015

Микро библиотека, которую я написал: https://github.com/pathikrit/better-files

file.write("Hi!")

или

file << "Hi!"
12 голосов
/ 09 февраля 2012

Вы можете легко использовать Apache File Utils . Посмотрите на функцию writeStringToFile. Мы используем эту библиотеку в наших проектах.

7 голосов
/ 14 февраля 2014

Это достаточно лаконично, наверное:

scala> import java.io._
import java.io._

scala> val w = new BufferedWriter(new FileWriter("output.txt"))
w: java.io.BufferedWriter = java.io.BufferedWriter@44ba4f

scala> w.write("Alice\r\nBob\r\nCharlie\r\n")

scala> w.close()
6 голосов
/ 04 сентября 2013

У этого также есть этот формат, который является одновременно кратким, и основная библиотека красиво написана (см. Исходный код):

import scalax.io.Codec
import scalax.io.JavaConverters._

implicit val codec = Codec.UTF8

new java.io.File("hi-file.txt").asOutput.write("I'm a hi file! ... Really!")
2 голосов
/ 06 января 2017

Я знаю, что это не одна строка, но насколько я могу судить, это решает проблемы безопасности;

// This possibly creates a FileWriter, but maybe not
val writer = Try(new FileWriter(new File("filename")))
// If it did, we use it to write the data and return it again
// If it didn't we skip the map and print the exception and return the original, just in-case it was actually .write() that failed
// Then we close the file
writer.map(w => {w.write("data"); w}).recoverWith{case e => {e.printStackTrace(); writer}}.map(_.close)

Если вам не нужна обработка исключений, вы можете написать

writer.map(w => {w.writer("data"); w}).recoverWith{case _ => writer}.map(_.close)
...