可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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:
回答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 the Scala compiler library:
scala.tools.nsc.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:
You can easily use Apache File Utils. Look at function writeStringToFile
. We use this library in our projects.
回答7:
A micro library I wrote: https://github.com/pathikrit/better-files
file.write("Hi!")
or
file << "Hi!"
回答8:
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!")
回答9:
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()
回答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:
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!
回答12:
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)
回答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()