Scala:在一个语句中将字符串写入文件

sma*_*007 135 scala scala-2.9

对于在Scala中读取文件,有

Source.fromFile("file.txt").mkString
Run Code Online (Sandbox Code Playgroud)

是否有一种等效和简洁的方法来将字符串写入文件?

大多数语言支持这样的东西.我最喜欢的是Groovy:

def f = new File("file.txt")
// Read
def s = f.text
// Write
f.text = "file contents"
Run Code Online (Sandbox Code Playgroud)

我想将代码用于从单行到短代码的程序.必须使用自己的库在这里没有意义.我希望有一种现代语言能让我方便地写一些文件.

有类似的帖子,但他们没有回答我的确切问题或专注于较旧的Scala版本.

例如:

Vla*_*eev 153

奇怪的是,没有人建议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))
Run Code Online (Sandbox Code Playgroud)

我认为这是迄今为止最简单,最简单,最惯用的方式,它不需要任何依赖Java本身.

  • 附加说明:如果你有一个文件,只需要'.toPath'来获取第一个参数. (3认同)
  • @javadba我们在JVM中,导入几乎不算"行",特别是因为替代方案几乎总是添加新的库依赖项.无论如何,`Files.write`也接受一个`java.lang.Iterable`作为第二个参数,我们可以使用转换器从Scala`Iterable`中获取它,即几乎任何集合类型:`import java.nio .file.{Files,Paths}; import scala.collection.JavaConverters.asJavaIterableConverter; val output = List("1","2","3"); Files.write(Paths.get("output.txt"),output.asJava)` (3认同)
  • 由于某种原因,这会忽略换行符。 (2认同)

Gar*_*all 81

这是一个使用reflect.io.file的简洁单行程序,这适用于Scala 2.12:

reflect.io.File("filename").writeAll("hello world")
Run Code Online (Sandbox Code Playgroud)

或者,如果您想使用Java库,您可以执行以下操作:

Some(new PrintWriter("filename")).foreach{p => p.write("hello world"); p.close}
Run Code Online (Sandbox Code Playgroud)

  • 建议不要这样做,因为scala.tools.nsc.io包不是公共API的一部分,而是由编译器使用. (25认同)
  • 好吧,如果写入抛出异常,如果您打算从异常中恢复并再次读取/写入文件,则可能需要关闭该文件.幸运的是,scala也提供了单行代码. (3认同)
  • "Some` /`foreach` hack正是为什么很多人讨厌Scala导致黑客无法生成的代码. (3认同)
  • `scala.tootls.nsc.io.File`是`reflect.io.File`的别名.仍然是内部API,但至少有点短. (3认同)

LRL*_*ena 69

简洁的一行:

import java.io.PrintWriter
new PrintWriter("filename") { write("file contents"); close }
Run Code Online (Sandbox Code Playgroud)

  • 虽然这种方法看起来不错,但它既不是异常安全的,也不是编码安全的.如果在`write()`中发生异常,则永远不会调用`close`,并且文件不会被关闭.`PrintWriter`也使用默认的系统编码,这对于可移植性来说非常糟糕.最后,这种方法专门为这一行生成一个单独的类(但是,考虑到Scala已经为一个简单的代码生成了大量的类,这本身并不是一个缺点). (12认同)
  • 对于临时调试日志,我使用`new PrintWriter(tmpFile){try {write(debugmsg)} finally {close}}` (2认同)

par*_*tic 40

如果你喜欢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 )

}
Run Code Online (Sandbox Code Playgroud)

它将按预期工作:

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
Run Code Online (Sandbox Code Playgroud)

  • 您永远不会在 Source.fromFile 返回的实例上调用 close ,这意味着资源在被 GCed (垃圾收集)之前不会关闭。并且您的 PrintWriter 没有缓冲,因此它使用 8 字节的微型 JVM 默认缓冲区,这可能会显着减慢您的 IO。我刚刚在处理这些问题的类似线程上创建了一个答案:http://stackoverflow.com/a/34277491/501113 (2认同)

xie*_*fei 22

import sys.process._
"echo hello world" #> new java.io.File("/tmp/example.txt") !
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案是__not__便携式!仅适用于*nix系统. (9认同)
  • 这不适用于编写任意字符串.它只适用于可以作为参数传递给命令行`echo`工具的短字符串. (2认同)

pat*_*rit 13

我写的一个微型库:https://github.com/pathikrit/better-files

file.write("Hi!")
Run Code Online (Sandbox Code Playgroud)

要么

file << "Hi!"
Run Code Online (Sandbox Code Playgroud)

  • 爱你的图书馆!这个问题是谷歌搜索如何使用scala编写文件时的热门搜索之一 - 现在你的项目已经变大了,你可能想稍微扩展你的答案吗? (2认同)

Ryu*_*Gan 12

您可以轻松使用Apache File Utils.看看功能writeStringToFile.我们在项目中使用这个库.

  • 我也经常使用它.如果你仔细阅读这个问题,我已经知道了为什么我不想使用图书馆. (3认同)

Lui*_*gro 7

这很简洁,我想:

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()
Run Code Online (Sandbox Code Playgroud)

  • 很公平,但这个"足够简洁"并没有被归类为"一个陈述":P (4认同)

Dib*_*eke 6

一个也有这种格式,既简洁又底层库写得很漂亮(参见源代码):

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!")
Run Code Online (Sandbox Code Playgroud)