web-dev-qa-db-ja.com

Scala:1つのステートメントでファイルに文字列を書き込む

Scalaでファイルを読み取るには、

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

文字列をファイルに書き込むための同等の簡潔な方法はありますか?

ほとんどの言語はそのようなものをサポートしています。私のお気に入りはGroovyです:

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

コードを1行から短いページの範囲のプログラムに使用したいと思います。ここでは、独自のライブラリを使用する必要はありません。現代の言語では、ファイルに何かを便利に書き込むことができると期待しています。

これに似た投稿がありますが、私の正確な質問に答えていないか、古いScalaバージョンに焦点を合わせています。

例えば:

134
smartnut007

簡潔な1行:

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

誰も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自体の依存関係は必要ないと思います。

152

次に、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}
80
Garrett Hall

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
40
paradigmatic
import sys.process._
"echo hello world" #> new Java.io.File("/tmp/example.txt") !
22
xiefei

Apache File Utils を簡単に使用できます。関数writeStringToFileを見てください。このライブラリをプロジェクトで使用します。

12
RyuuGan

私が書いたマイクロライブラリ: https://github.com/pathikrit/better-files

file.write("Hi!")

または

file << "Hi!"
12
pathikrit

これは十分に簡潔です、私は推測します:

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

また、この形式があります。これは簡潔であり、基礎となるライブラリが美しく書かれています(ソースコードを参照)。

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

1行ではないことは知っていますが、私が知る限り、安全性の問題は解決しています。

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

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

更新:私はここで詳しく説明したより効果的なソリューションを作成しました: https://stackoverflow.com/a/34277491/50111

EclipseのScala Scala内のIDE Worksheetでますます動作していることがわかります(IntelliJ IDEAに同等のものがあると思います)。とにかく、「出力がカットオフ制限を超えています」というメッセージが表示されたら、ワンライナーを実行してコンテンツの一部を出力できる必要があります。特にScalaコレクションを使用して重要なことをしている場合は、メッセージ。

これを簡素化するために、各新しいScalaワークシートの上部に挿入する1ライナーを思い付きました(したがって、非常に単純な必要性のために外部ライブラリのインポート全体を実行する必要はありません)。あなたがステッカーであり、それが技術的に2行であることに気づいた場合、それはこのフォーラムでそれをより読みやすくすることです。 Scala Worksheetの1行です。

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

これにより、デフォルト以外のファイルを追加したい場合に、オプションでファイル名を指定できます(メソッドが呼び出されるたびにファイルが完全に上書きされます)。

したがって、2番目の使用法は単純です。

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

楽しい!

1

セミコロンの魔法を通して、ワンライナーのようなものを作ることができます。

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()
0
Ion Freeman