CLOVER🍀

That was when it all began.

いろんな言語で、文字コードを指定してファイル書き込み

Readをやったので、今度はWriteということで。

記載パターンは、以下の2通り。

  • 変数messageに格納された文字列を一括してファイル出力
  • 改行を含まない文字列リストmessagesに対して、行末に改行(LF)を付与してファイル出力

今回も、前提はこんな感じです。

では、いってみましょう。

Java

書き込みについても、JDK 7からはやっぱり楽になりましたね。
今回も雛形コードから。

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.List;

public class WriteFile {
    public static void main(String[] args) {
        try {
            // code here...
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

コメント「// code here...」の部分を埋めていきます。

文字列を一括して出力する方から。

            String message = "こんにちは、世界\nそして、さようなら\n";
            Files.write(Paths.get("output.txt"), message.getBytes(StandardCharsets.UTF_8));
            //Files.write(Paths.get("output.txt"), message.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE);

java.nio.file.Files#writeで、バイト配列の一括出力が可能なことを利用しています。第3引数には、ファイルを開く時のオプションを指定可能です。コメントアウトしている方が、デフォルトのオプションのようです。

続いて、Listを出力する方へ。

            List<String> messages = Arrays.asList("こんにちは、世界", "そして、さようなら");
            Files.write(Paths.get("output.txt"), messages, StandardCharsets.UTF_8);

改行は勝手にくっつきます。しかも、プラットフォーム依存なので、考え方によってはちょっと微妙かも…。

読み込みと同じく、クローズ処理は不要です。

Groovy

NIO.2も使えますが、ここではGDKで考えます。
まずは文字列出力から。

def message = "こんにちは、世界\nそして、さようなら\n"
new File('output.txt').write(message, 'UTF-8')

やっぱり、楽。

ただ、リスト出力するようなメソッドはないので、あくまでGDKでやろうとすると、こんな感じ?

def messages = ["こんにちは、世界", "そして、さようなら"]
new File('output.txt').write(messages.collect { it + "\n" }.join(''), 'UTF-8')

もしくは、こう?

def messages = ["こんにちは、世界", "そして、さようなら"]
new File('output.txt').withWriter('UTF-8') { w -> messages.each { w.write("$it\n") } }

Scala

Javaと同じです。

import scala.collection.JavaConverters._

import java.nio.charset.StandardCharsets
import java.nio.file.{Files, Paths, StandardOpenOption}

val message = """|こんにちは、世界
                 |そして、さようなら
                 |""".stripMargin
Files.write(Paths.get("output.txt"), message.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)

val messages = List("こんにちは、世界", "そして、さようなら")
Files.write(Paths.get("output.txt"), messages.asJava, StandardCharsets.UTF_8)

まあ、Scalaは標準ライブラリにファイル出力可能なクラスってないですからねぇ…。

Perl

文字列一括出力から。
#!/usr/bin/perl

use strict;
use warnings;
use utf8;

my $message = <<EOS;
こんにちは、世界
そして、さようなら
EOS

my $output_file = 'output.txt';
open my $file, '>:encoding(utf8)', $output_file or die qq{Can't open file: "$output_file"\n};
print $file $message;
close $file;

続いて、リスト渡し。

#!/usr/bin/perl

use strict;
use warnings;
use utf8;

my @messages = ("こんにちは、世界", "そして、さようなら");
my $output_file = 'output.txt';
open my $file, '>:encoding(utf8)', $output_file or die qq{Can't open file: "$output_file"\n};
print $file map { "$_\n" } @messages;
close $file;

思っていたよりも楽でした。まあ、リスト内の文字列に改行をくっつける処理がはいってますけどね…。

Python

Perlと似たような感じですね。
文字列一括出力。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import codecs

message = u"""こんにちは、世界
そして、さようなら
"""

f = codecs.open("output.txt", "w", "utf-8")
try:
    f.write(message)
finally:
    f.close()

続いて、リストを使用して出力。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import codecs

messages = [u"こんにちは、世界", u"そして、さようなら"]
f = codecs.open("output.txt", "w", "utf-8")
try:
    f.writelines(map(lambda word: word + "\n", messages))
finally:
    f.close()

writelinesというメソッドがあるので、リストが渡せます。改行は、その前にmap関数でくっつけていますが。