Для чтения файлов в Scala существует
Source.fromFile("file.txt").mkString
Есть ли эквивалентный и сжатый способ записи строки в файл?
Большинство языков поддерживают что-то подобное. Мой любимый Groovy:
def f = new File("file.txt")
// Read
def s = f.text
// Write
f.text = "file contents"
Я хотел бы использовать код для программ, начиная от одной строки и заканчивая короткой страницей кода. Для использования вашей собственной библиотеки здесь нет смысла. Я ожидаю, что современный язык позволит мне написать что-то в файл удобно.
Есть сообщения, похожие на это, но они не отвечают на мой точный вопрос или ориентированы на более старые версии Scala.
Например:
Краткая одна строка:
new PrintWriter("filename") { write("file contents"); close }
write()
происходит исключение, close
никогда не будет вызываться, и файл не будет закрыт. PrintWriter
также использует системную кодировку по умолчанию, что очень плохо для переносимости. И наконец, этот подход генерирует отдельный класс специально для этой строки (однако, учитывая, что Scala уже генерирует тонны классов даже для простого кода, сам по себе это вряд ли является недостатком).
Странно, что никто не предлагал операции 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.
Ниже приведен краткий однострочный файл с использованием библиотеки компилятора Scala:
scala.tools.nsc.io.File("filename").writeAll("hello world")
В качестве альтернативы, если вы хотите использовать библиотеки Java, вы можете сделать этот взлом:
Some(new PrintWriter("filename")).foreach{p => p.write("hello world"); p.close}
Some
/ foreach
немного прикольная, но в ней нет преимущества try / catch / finally.
Если вам нравится синтаксис 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
import sys.process._
"echo hello world" #> new java.io.File("/tmp/example.txt") !
Вы можете легко использовать Apache File Utils. Посмотрите на функцию writeStringToFile
. Мы используем эту библиотеку в наших проектах.
Микробиблиотека, которую я написал: https://github.com/pathikrit/better-files
file.write("Hi!")
или
file << "Hi!"
У одного также есть этот формат, который является и кратким, и основная библиотека красиво написана (см. исходный код):
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!")
Это достаточно кратким, я думаю:
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()
Вы можете сделать это с помощью сочетания 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"))
Я знаю, что это не одна строка, но она решает проблемы безопасности, насколько я могу судить,
// 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)
ОБНОВЛЕНИЕ: с тех пор я создал более эффективное решение, на котором я подробно остановился здесь: https://stackoverflow.com/questions/4604237/how-to-write-to-a-file-in-scala
Я все больше и больше работаю в Scala Рабочем листе в Scala IDE для Eclipse (и я считаю, что в 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")
Наслаждайтесь!
Через волшебство точки с запятой вы можете сделать все, что вам нравится, с одним слоем.
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()