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の公式解説ページ群](https://docs.oracle.com/cd/E26537_01/tutorial/essential/io/index.html)
・[java.io.File のコードを java.nio.Path と java.nio.Files を使って書き直す](https://qiita.com/toastkidjp/items/5500521ff5dc0346c2b1)
・[Javaのファイル入出力関係のクラス/インタフェースについて整理する](https://qiita.com/anqooqie/items/0ac128f52e2e5153f727)