【Java】「エスケープ文字が不正です」「エンコーディングMS932にマップできません」の対処メモ

こんばんは。

今、自分の中で一大プロジェクトを進行中です。
（頓挫するかも知れないので内容は伏せます・・いつかここで公開できたら！）

その中のごく一部のプログラムを作るために、Javaでテキストの読み込み・出力ができるプログラムを作っています。
windows10になってから、デフォルトの文字コードがUTF-8になりました。
VbscriptでUTF-8のファイルの入出力を組もうと思ったのですが、従来のShift-Jis専用の処理だと文字化けしてしまいます。
Vbscript使いの皆さんは、コーディング方法を変えた感じでしょうか？
例）テキストファイルのレコードを読み込む処理
dataline = inStream.readline
　　　　　　↓
dataline = inStream.readtext(-2)
自分の会社のPCには、Vbscriptのツールが大量に保存してあるので、どうやって対応していこうかなあと悩み中です。
まあそんな事もあり、せっかくなので勉強中のJavaで組もうと思った次第です。
そこで発生したコンパイルエラーについて、対処しましたのでメモとして投稿します。

#先に結論
発生したエラーは2つ。それぞれ対処を→で記載します。

・エラー: この文字は、エンコーディングMS932にマップできません
　→①コンパイル時に「-encoding UTF-8」などの指定をして、コーディングした
　　ソースファイルのエンコーディングに合わせてコンパイルする
　→②ソースファイル保存時に、デフォルトエンコーディング（今回の場合はMS932ですが
　　これはShift-Jisの拡張版のイメージなので、'ANSI’）で保存する
・エラー: エスケープ文字が不正です
　→エスケープすべき文字列を、エスケープシーケンスを使う等して
　　対応する（'\'→'\\'等）

#作ったプログラム

さて、以下のようなプログラムを組みました。
処理としては非常に単純で、テキストファイルを読み込んで画面に出力する処理です。
（某サイトのサンプルプログラムを拝借させていただきました）

```java:readtest.java
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;

public class readtest{
public static void main(String args[]){
try{
//err1  File file = new File("C:\Users\ドキュメント\Java1\sinki\K0040d.txt");
//err2  File file = new File("C:\\Users\\ドキュメント\\Java1\\sinki\\K00401.txt");
  File file = new File("K0040d.txt");
  BufferedReader br = new BufferedReader(new FileReader(file));

  String str = br.readLine();
  while(str != null){
    System.out.println(str);

    str = br.readLine();
  }

  br.close();
}catch(FileNotFoundException e){
  System.out.println(e);
}catch(IOException e){
  System.out.println(e);
}

}
}
```
まず、'err1'となっているところです。
```//err1  File file = new File("C:\Users\ドキュメント\Java1\sinki\K0040d.txt");```
ここを有効にしてコンパイルすると、以下のエラーが出力されまくります。

```
readtest.java:13: エラー: この文字は、エンコーディングMS932にマップできません
//  File file = new File("C:\\Users\\繝峨く繝･繝｡繝ｳ繝?\\Java1\\sinki\\K0040d.txt");
                                               ^
readtest.java:10: エラー: エスケープ文字が不正です
  File file = new File("C:\Users\繝峨く繝･繝｡繝ｳ繝?\Java1\sinki\K0040d.txt");
                           ^
```

理由は簡単で、パスを指定するときは'\'をエスケープしてあげないといけないためです。なので、'\'→'\\\'にします。

これを対応したのがerr2。
```//err2  File file = new File("C:\\Users\\ドキュメント\\Java1\\sinki\\K00401.txt");```

（ちなみに最終的には絶対パスを指定するのはやめ、ファイル名のみにしました。
　読み込みたいテキストファイルは同じフォルダに格納されていたので、これでも大丈夫でした）

その後、コンパイルするとエスケープ文字のエラーだけが解決したみたいですが以下のエラーは残ってしまいます。

```
readtest.java:13: エラー: この文字は、エンコーディングMS932にマップできません
//  File file = new File("C:\\Users\\繝峨く繝･繝｡繝ｳ繝?\\Java1\\sinki\\K0040d.txt");
                                              ^
```
まず自分の開発する環境のデフォルトエンコーディングを認識しておく必要があります。それと異なる文字コードでソースファイルを扱ってしまうと、上記のエラーになります。

以下のサイトに記載のあったプログラムでデフォルトエンコーディングを確認すると、MS932になっていました。
https://www.javadrive.jp/start/encoding/index2.html

対して、今回組んだJavaのプログラムのファイルは、テキストファイルの保存時に
「UTF-8」を選択しています。
その場合は、MS932の文字コードで読み込むことができずエラーになります。

対策は2つ。
・ファイル保存時に「ANSI」で保存する。
・コンパイル時に、以下の指定をしてコンパイルする。
　```javac -encoding UTF-8 readtest.java```
　「-encoding xxx」のxxxに使用している文字コード
　（エンコードしたい文字コード）を指定する。
　
これで実行したところ、テキストファイルの内容が出た出た！わーいわーい。
`2020/03/20      xxx     -100
 2020/04/20      xxx     -100
 2020/05/18      xxx     -100
 2020/06/20      xxx     -100
 2020/07/20      xxx     -100
 2020/08/20      xxx     -100
 2020/09/20      xxx     -100`

（テキストファイルの中身に意味はありません）

という事で、テキストファイルの読み込み・画面出力ができたところで今日はここまで。
こんな感じでコツコツとアウトプットしていきたいと思います。

ではまた。