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

时间:2011-07-29 21:54:01

标签: scala scala-2.9

对于在Scala中读取文件,有

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

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

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

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

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

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

例如:

16 个答案:

答案 0 :(得分:146)

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

答案 1 :(得分:78)

这是一个使用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}

答案 2 :(得分:64)

简洁的一行:

import java.io.PrintWriter
new PrintWriter("filename") { write("file contents"); close }

答案 3 :(得分: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 )

}

它将按预期工作:

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

答案 4 :(得分:22)

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

答案 5 :(得分:12)

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

答案 6 :(得分:12)

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

file.write("Hi!")

file << "Hi!"

答案 7 :(得分: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!")

答案 8 :(得分:6)

这很简洁,我想:

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

答案 9 :(得分: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"))

答案 10 :(得分:2)

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

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt


%matplotlib inline
%config InlineBackend.figure_format = 'svg'



x = [106405611, 107148674, 107151119, 107159869, 107183396, 107229405, 107231917, 107236097,
 107239994, 107259338, 107273842, 107275873, 107281000, 107287770, 106452671, 106471246, 
 106478110, 106494135, 106518400, 106539079]


y = np.array([  9.09803208,   5.357552  ,   8.98868469,   6.84549005,
         8.17990909,  10.60640521,   9.89935692,   9.24079133,
         8.97441459,   9.09803208,  10.63753055,  11.82336724,
         7.93663794,   8.74819285,   8.07146236,   9.82336724,
         8.4429435 ,  10.53332973,   8.23361968,  10.30035256])


x1 = pd.Series(x, name="$V$")
x2 = pd.Series(y, name="$Distance$")  

col = np.array([2, 4, 4, 1, 3, 4, 3, 3, 4, 1, 4, 3, 2, 4, 1, 1, 2, 2, 3, 1])

g = sns.JointGrid(x1, x2)
g = g.plot_joint(plt.scatter, color=col, edgecolor="black", cmap=plt.cm.get_cmap('RdBu', 11))
cax = g.fig.add_axes([1, .25, .02, .4])
plt.colorbar(cax=cax, ticks=np.linspace(1,11,11))
g.plot_marginals(sns.kdeplot, color="black", shade=True)

如果您不关心异常处理,那么您可以编写

// 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)

答案 11 :(得分:2)

使用ammonite ops库。语法非常简单,但是该库的宽度几乎与使用bash这样的shell脚本语言尝试这种任务所期望的宽度一样。

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

import ammonite.ops._
write(pwd/'"file.txt", "file contents")

答案 12 :(得分:1)

更新:我已经创建了一个更有效的解决方案,我在此详细阐述过:https://stackoverflow.com/a/34277491/501113

我发现自己在Scala IDE for Eclipse中的Scala工作表中越来越多地工作(我相信在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")

享受!

答案 13 :(得分:1)

这是现代、安全的单衬:

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

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

答案 14 :(得分:0)

通过分号的魔力,你可以制作任何你喜欢的单线。

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

答案 15 :(得分:0)

os-lib是写入文件as mentioned here的最佳现代方式。

以下是将“ hello”写入file.txt文件的方法。

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

os-lib隐藏了Java的丑陋和复杂性(它在后台使用了Java libs,因此性能一样)。有关使用该库的更多信息,请参见here