Scala: write string to file in one statement

牧云@^-^@ 提交于 2019-11-26 11:53:03

问题


For reading files in Scala, there is

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

Is there an equivalent and concise way to write a string to file?

Most languages support something like that. My favorite is Groovy:

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

I\'d like to use the code for programs ranging from a single line to a short page of code. Having to use your own library doesn\'t make sense here. I expect a modern language to let me write something to a file conveniently.

There are posts similar to this, but they don\'t answer my exact question or are focused on older Scala versions.

For example:

  • Read entire file in Scala?
  • How to write to a file in Scala?

回答1:


A concise one line:

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



回答2:


It is strange that no one had suggested NIO.2 operations (available since 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))

I think this is by far the simplest and easiest and most idiomatic way, and it does not need any dependencies sans Java itself.




回答3:


Here is a concise one-liner using reflect.io.file, this works with Scala 2.12:

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

Alternatively, if you want to use the Java libraries you can do this hack:

Some(new PrintWriter("filename")).foreach{p => p.write("hello world"); p.close}



回答4:


If you like Groovy syntax, you can use the Pimp-My-Library design pattern to bring it to 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 )

}

It will work as expected:

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



回答5:


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



回答6:


A micro library I wrote: https://github.com/pathikrit/better-files

file.write("Hi!")

or

file << "Hi!"



回答7:


You can easily use Apache File Utils. Look at function writeStringToFile. We use this library in our projects.




回答8:


This is concise enough, I guess:

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:


One also has this format, which is both concise and the underlying library is beautifully written (see the source code):

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!")



回答10:


You can do this with a mix of Java and Scala libraries. You will have full control over the character encoding. But unfortunately, the file handles will not be closed properly.

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



回答11:


I know it's not one line, but it solves the safety issues as far as I can tell;

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

If you didn't care about the exception handling then you can write

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



回答12:


UPDATE: I have since created a more effective solution upon which I have elaborated here: https://stackoverflow.com/a/34277491/501113

I find myself working more and more in the Scala Worksheet within the Scala IDE for Eclipse (and I believe there is something equivalent in IntelliJ IDEA). Anyway, I need to be able to do a one-liner to output some of the contents as I get the "Output exceeds cutoff limit." message if I am doing anything significant, especially with the Scala collections.

I came up with a one-liner I insert into the top of each new Scala Worksheet to simplify this (and so I don't have to do the whole external library import exercise for a very simple need). If you are a stickler and notice that it is technically two lines, it's only to make it more readable in this forum. It is a single line in my Scala Worksheet.

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

And the usage is simply:

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

This allows me to optionally provide the file name should I want to have additional files beyond the default (which completely overwrites the file each time the method is called).

So, the second usage is simply:

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

Enjoy!




回答13:


Through the magic of the semicolon, you can make anything you like a one-liner.

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


来源:https://stackoverflow.com/questions/6879427/scala-write-string-to-file-in-one-statement

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!