Edited at

Java New FileIOを使ってみよう!(入門, 初心者向け)


きっかけ

学校でJavaを教えているのでその時の資料から作ってみました。


語句の説明

とりあえず、語句の説明を。


FileIOってなんだよ?

ファイルシステム(file system)のI (Input / 入力) と O (Output / 出力) を行えるよ!


ファイルシステムってなんやねん!!

ファイルシステムとは、OSにおいてデータを保管するファイル(File)とそれをまとめ上げて管理するディレクトリー(Directory/Folder)で作られる世界のこと。


はじめに


FileIOで何ができるん?

ファイルとディレクトリーに対して、delete(削除), create(作成), exist(存在確認),…,write(書き込み), read(読み込み)などいろいろ、私達がOSで行うこと(たぶん)すべてができる!


じゃぁJavaでそれを行うにはどうすればいいの?

→NewIOというJavaの標準ライブラリがおすすめですよ!

旧来はFile(java.io系)というクラスを中心として構成されていたが、現在では便利で最適化されているなどの様々な利点からNew I/O(java.nio系)というパッケージを用いて行うのがこれからの主流となっています(させます)。


NewIOを使ってみよう


NewIOを始めるにあたって

NewIOでは一般的に次の2つ(3つ)のクラスが基礎的な役割を持ちます。

Path: Stringを変換してファイルのパスを表すようにしたクラス

Paths: Pathを作るためのクラス
Files: 実際にファイル操作をするクラス

※FileクラスはNewIOではなく、古のもの(NewIOでないOldなIO系)のため注意すべし。


Pathの取得

Pathの取得(例) … ファイルの場所!

Path path = Paths.get(“C:\\”, “a”);

※Pathはnewでは作れません!

※Pathsのgetメソッドはstaticメソッドです!

※getメソッドの引数は、可変長引数で、引数ごとで、ファイルの階層を表すことができます。

※パス(普通に文字列)の取得は、ファイルを選択して、Shift+右クリックで「パスのコピー」を行うと楽。

※パスは、エスケープシークエンスとダブルクオーテーションに気をつける。


Filesの利用例

Filesの利用の例 … ファイル/ディレクトリーに対する操作を行う。

Files.exsit(path);

※戻り値はbooleanなのでこれをif文で使うことができる!


ファイルへの読み書き

基本的に次の2つのクラスを使うと良い。(ほかのクラスは基本的に古のものが多いが、他人のプログラムでは古でも使われることが多いので注意?してください)

BufferedWriter: バッファを用いて効率的に、ファイルに書き込みを行うクラス

BufferedReader: バッファを用いて効率的に、ファイルに読み込みを行うクラス


Buffer(バッファ)って?

メモリ空間上に一時的に置かれたデータのこと。tmp/temp(テンプ)ともいいます。


BufferedWriter/BufferedReaderの(インスタンスの)生成


古の方法

たぶん、(NewIOでは)あんまり使わないです。

BufferedWriter bw = new BufferedWriter(Writer);

BufferedReader br = new BufferedReader(Reader);


NewIOを用いた、BufferedWriter/BufferedReaderの生成

BufferedWriter bw = Files.newBufferedWriter(path);


BufferedWriter/BufferedReaderの利用

bw.write(String);

String line = br.readLine();

※bw, brはそれぞれclose()メソッドを呼び出さないと行けない。

(why -> bwでclose()を呼び出さないと出力されない, flush()の呼び出し)

try {

BufferedWriter bw = Files.newBufferedWriter(path);
bw.write(“A”);
bw.close();
} catch (IOException ex) {
ex.printStackTrace();
}

また、closeで例外が発生する恐れがあり、closeに対する例外処理必要が必要でもある。

よって以下のようにする必要がある。

try {

BufferedWriter bw = Files.newBufferedWriter(path);
bw.write(“A”);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
bw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}

クソ長い


BufferedWriter/BufferedReaderの利用(改良) ~ try-catch-resouce!

先程のように書くと凄く長い。そこでJava7からtry-catch-resouce構文が追加され、以下のように簡潔に書けるようになった。

try (BufferedWriter bw = Files.newBufferedWriter(path)) {

bw.write(“A”);
}

めっちゃいい。

参考: https://qiita.com/Takmiy/items/a0f65c58b407dbc0ca99


改行をするには?(write()の利用)

br.write(text)を呼び出しただけでは、改行されず、

br.write("AA");

br.write("BB");

AABB

みたいなことになってしまう。

改行するには、行の文字列の最後に改行文字をつければ良い。

bw.write(text + System.lineSeparator());

※System.lineSeparator();はOS毎に正しい改行文字を返してくれるメソッド。

CRLF(\r\n), LF(\n)とかの差異に気をつけなくて良い!(改行文字については調べよう)


課題

1.ファイルに文字列を書き込む

2.「1.」の複数行version (Listを用いて)

3.ファイルの読み込み

4.「3.」の複数行version (Listを用いて行の表現), なお全ての行でも良いし、任意の範囲の行でも良い。


コラム

私達が今まで使ってきたいつもの構文について…

System.out.println(“Hello world!”);

これをFileIOを理解した上でみるとなんだかFileIOっぽいなぁと思いますよね。

どういうこと?ってなりますけど。

実は、System.out (のout)は、OutputStreamなのである!ということ。(つまり出力用)

一応、StreamというのはFileIOを抽象化したものです。(たぶん)

同様に、System.in というものもありますが、これはInputStreamです。(つまり入力用)

しかしながら、これは考えれば自然で、コンソールに文字を書くことって、実際はファイルに文字を書くこととあまり変わりないですよね(自分はこういう共通化するという所が面白いなーと思いました)。


参考/Reference

Oracleの公式解説ページ群

java.io.File のコードを java.nio.Path と java.nio.Files を使って書き直す

Javaのファイル入出力関係のクラス/インタフェースについて整理する