Scala: записать строку в файл одним оператором

Для чтения файлов в Scala есть

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

Есть ли эквивалентный и краткий способ записать строку в файл?

Большинство языков поддерживают что-то подобное. Мой любимый это Groovy:

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

Я хотел бы использовать код для программ, начиная от одной строки до короткой страницы кода. Необходимость использовать свою собственную библиотеку здесь не имеет смысла. Я ожидаю, что современный язык позволит мне удобно что-то записывать в файл.

Есть сообщения, подобные этому, но они не отвечают на мой точный вопрос или ориентированы на более старые версии Scala.

Например:

17 ответов

Решение

Краткая строчка:

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

Странно, что никто не предлагал операции 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}

Если вам нравится синтаксис 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") !

Микро библиотека, которую я написал: https://github.com/pathikrit/better-files

file.write("Hi!")

или же

file << "Hi!"

Вы можете легко использовать Apache File Utils. Посмотрите на функцию writeStringToFile, Мы используем эту библиотеку в наших проектах.

Это достаточно кратко, я думаю:

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

У одного также есть этот формат, который является и кратким, и основная библиотека написана красиво (см. Исходный код):

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

Я знаю, что это не одна строка, но насколько я могу судить, она решает проблемы безопасности;

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

Используйте библиотеку операций аммонита. Синтаксис очень минимален, но ширина библиотеки почти такая же, как и следовало ожидать от попытки выполнения такой задачи на языке сценариев оболочки, таком как bash.

На странице, на которую я указал, показаны многочисленные операции, которые можно выполнять с библиотекой, но чтобы ответить на этот вопрос, это пример записи в файл.

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

ОБНОВЛЕНИЕ: с тех пор я создал более эффективное решение, которое я разработал здесь: /questions/748759/kak-zapisat-v-fajl-v-scala/748779#748779

Я все больше и больше работаю над рабочим листом Scala в Scala IDE для Eclipse (и я считаю, что в IntelliJ IDEA есть что-то эквивалентное). В любом случае, мне нужно иметь возможность сделать одну строку для вывода некоторого содержимого, так как я получаю "Вывод превышает предел отсечения". сообщение, если я делаю что-то значительное, особенно с коллекциями Scala.

Я придумал однострочную вставку, которую я вставляю в верхнюю часть каждого нового рабочего листа Scala, чтобы упростить это (и поэтому мне не нужно выполнять целое упражнение по импорту внешних библиотек для очень простой необходимости). Если вы сторонник и заметили, что это технически две строки, это только для того, чтобы сделать его более читабельным на этом форуме. Это единственная строка в моем 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}}

И использование просто:

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

Это позволяет мне при желании указать имя файла, если я хочу иметь дополнительные файлы за пределами по умолчанию (который полностью перезаписывает файл при каждом вызове метода).

Итак, второе использование просто:

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

Наслаждайтесь!

Вот современный и безопасный лайнер:

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

nio - это современная библиотека ввода-вывода, поставляемая по умолчанию с JDK 9+, поэтому импорт или зависимости не требуются.

Вы можете сделать это с помощью библиотек 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"))
      import java.nio.file.{Files, Paths}

Files.writeString(
   Paths.get(theFilePathString),
   thePayloadString
)

(UTF-8 неявно)

начиная с Явы 11

С помощью магии точки с запятой вы можете сделать все, что вам нравится, в одну строку.

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

os-lib - это лучший современный способ записи в файл, как упоминалось здесь .

Вот как написать "привет" file.txt файл.

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

os-lib скрывает уродство и сложность Java (он использует библиотеки Java под капотом, поэтому он такой же производительный). См. Здесь дополнительную информацию об использовании библиотеки lib.

Другие вопросы по тегам