166

对于在 Scala 中读取文件,有

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

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

大多数语言都支持类似的东西。我最喜欢的是 Groovy:

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

我想将代码用于从单行到一小段代码的程序。必须使用自己的库在这里没有意义。我希望有一种现代语言可以让我方便地向文件写入内容。

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

例如:

4

16 回答 16

182

奇怪的是没有人建议过 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 本身的依赖项。

于 2014-05-28T16:33:02.067 回答
87

简洁的一行:

import java.io.PrintWriter
new PrintWriter("filename") { write("file contents"); close }
于 2015-06-01T15:45:04.870 回答
86

这是使用 reflect.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}
于 2013-02-11T20:07:52.913 回答
42

如果您喜欢 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
于 2011-07-30T07:30:05.230 回答
23
import sys.process._
"echo hello world" #> new java.io.File("/tmp/example.txt") !
于 2012-02-08T12:42:27.377 回答
18

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

file.write("Hi!")

或者

file << "Hi!"
于 2015-09-14T19:42:12.513 回答
12

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

于 2012-02-09T05:22:59.953 回答
7

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

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!")
于 2013-09-04T18:10:54.463 回答
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()
于 2014-02-14T11:13:17.490 回答
2

您可以通过混合使用 Java 和 Scala 库来做到这一点。您将完全控制字符编码。但不幸的是,文件句柄不会正确关闭。

scala> import java.io.ByteArrayInputStream
import java.io.ByteArrayInputStream

scala> import java.io.FileOutputStream
import java.io.FileOutputStream

scala> BasicIO.transferFully(new ByteArrayInputStream("test".getBytes("UTF-8")), new FileOutputStream("test.txt"))
于 2013-08-09T16:32:10.560 回答
2

更新:我已经创建了一个更有效的解决方案,我在这里详细说明:https ://stackoverflow.com/a/34277491/501113

我发现自己在 Scala IDE for Eclipse 中的 Scala Worksheet 中工作越来越多(我相信 IntelliJ IDEA 中也有类似的东西)。无论如何,当我得到“输出超出截止限制”时,我需要能够做一个单行来输出一些内容。如果我正在做任何重要的事情,尤其是 Scala 集合,请发送消息。

我想出了一个插入到每个新 Scala 工作表顶部的单行来简化这一点(因此我不必为非常简单的需要执行整个外部库导入练习)。如果您是一个坚持不懈的人并且注意到它在技术上是两行,那只是为了使它在这个论坛中更具可读性。这是我的 Scala 工作表中的一行。

def printToFile(content: String, location: String = "C:/Users/jtdoe/Desktop/WorkSheet.txt") =
  Some(new java.io.PrintWriter(location)).foreach{f => try{f.write(content)}finally{f.close}}

用法很简单:

printToFile("A fancy test string\ncontaining newlines\nOMG!\n")

如果我想拥有超出默认值的其他文件(每次调用该方法时会完全覆盖文件),这允许我有选择地提供文件名。

所以,第二种用法很简单:

printToFile("A fancy test string\ncontaining newlines\nOMG!\n", "C:/Users/jtdoe/Desktop/WorkSheet.txt")

享受!

于 2013-10-31T21:59:24.497 回答
2

我知道这不是一条线,但据我所知,它解决了安全问题;

// 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)
于 2017-01-06T18:57:34.963 回答
2

使用ammonite ops库。语法非常少,但库的广度几乎与使用 bash 等 shell 脚本语言尝试此类任务所期望的一样广泛。

在我链接到的页面上,它显示了可以对库执行的许多操作,但要回答这个问题,这是一个写入文件的示例

import ammonite.ops._
write(pwd/'"file.txt", "file contents")
于 2020-01-27T19:15:08.120 回答
2

这是现代、安全的单班轮:

java.nio.file.Files.write(java.nio.file.Paths.get("/tmp/output.txt"), "Hello world".getBytes());

nio 是一个现代 IO 库,默认情况下随 JDK 9+ 一起提供,因此不需要导入或依赖项。

于 2021-02-23T15:09:35.680 回答
0

os-lib是写入文件的最佳现代方式,如此处所述

以下是如何将“hello”写入file.txt文件。

os.write(os.pwd/"file.txt", "hello")

os-lib 隐藏了 Java 的丑陋和复杂性(它在底层使用了 Java 库,因此它同样具有高性能)。有关使用 lib 的更多信息,请参见此处

于 2020-12-14T03:33:45.097 回答
-1

通过分号的魔力,您可以制作任何您喜欢的单行字。

import java.io.PrintWriter
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.charset.StandardCharsets
import java.nio.file.StandardOpenOption
val outfile = java.io.File.createTempFile("", "").getPath
val outstream = new PrintWriter(Files.newBufferedWriter(Paths.get(outfile)
  , StandardCharsets.UTF_8
  , StandardOpenOption.WRITE)); outstream.println("content"); outstream.flush(); outstream.close()
于 2017-02-16T20:22:26.177 回答