今回やりたいこと
今回は、Javaファイルの操作についてバイナリデータを扱うケースを紹介します。
具体的にはファイルに保存する時にバイナリデータに変換して保存してみることと、保存したファイルをバイナリデータとして保存して、文字列に変換することで元の文字列が復元して表示されるかをやってみます。
なぜバイナリデータでの保存と読み込みが必要なのか?
テキストデータをそのままファイルに保存することもありますが、バイナリデータでの保存と読み込みを行うことは、固定長でフラグやデータをバイナリデータとして保存することで、データの保存と読み込みが出来るようになります。
また、保存したデータの可読性が下がることで、簡単にデータを分析することが出来なくなり、データを改造するとシステムが使えなくなるなどといったセキュリティ面での対策としても期待が持てます。
そのため、バイナリデータとしてファイルを保存、読み込みすることは実践で使うことはWeb系ではあまり使うことはないかもしれませんが(使うとしたら他のシステムとの連携データを出力する時くらいです)、スタンドアロンのプログラムを作る場合だと(特にゲームの保存データやリソースデータの場合)、バイナリデータとして保存、読み込みを行うメリットが出てきます。
バイナリデータを保存する処理
では、早速バイナリデータをファイルに保存する処理を紹介していきます。
前準備として、以下の定数を定義しておきます。
//バイナリ情報を出力するファイル名
public static final String FILEPATH="binary.bin";
//バイナリデータ化する
public static final String FILEDATA="この文章はサンプルです";
そして、バイナリデータをファイルに保存する処理を以下のように定義します。
public static void writeBin() {
//ファイルに書き込む
try (FileOutputStream fos = new FileOutputStream(FILEPATH);
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream dos = new DataOutputStream(bos)) {
//この処理でUTF_8コードでバイナリデータ化する
byte[] byteData = FILEDATA.getBytes(StandardCharsets.UTF_8);
//バイナリデータを1つずつファイルに書き込んでいく
for(int i = 0; i < byteData.length; i++) {
dos.writeByte(byteData[i]);
}
}
catch (Exception e){
//エラーがあれば実行する
e.printStackTrace();
}
}
3行目から5行目はファイルデータ出力のストリームの設定をしており、ファイルにデータを書き込む準備みたいなものです。
7行目で書き込む対象のデータであるFILEDATA(”この文章はサンプルです”の文章)をバイナリデータに変換しています。
9~11行目で、変換したバイナリデータを一つずつファイルに書き込んでいます。
実際にこの処理を動作させると以下のようにFILEPATHで定義した、binary.binが出来ました。
そして、このbinary.binをテキストエディタで開いてみると、データが書かれている様子が確認できました(今回はテキスト文書をバイナリデータに変換して保存したため、テキスト文章がそのまま表示されています)。
上記の確認で、ファイルがバイナリデータとしてきちんと保存されていることが確認できました。
バイナリデータとしてファイルを読み込み、文字列に変換してコンソールに表示する処理
今度はバイナリデータを読み込み、文字列に変換してコンソールに表示してみます。
ファイル読み込みは以下のようにコードを書きます。
//バイナリーデータを読み込んでコンソールに表示
public static void readBin() {
try (DataInputStream dis = new DataInputStream(new FileInputStream(FILEPATH))) {
//バイナリデータを読み込み、文字列に変換する
byte[] readByte = dis.readAllBytes();
String readStr = new String(readByte, StandardCharsets.UTF_8);
//読み込んだ内容をコンソールに出力
System.out.println("読み込んだバイナリーデータ:" + readByte);
System.out.println("バイナリデータから復元した文字列:" + readStr);
}
catch (Exception e){
//エラーがあればnullで返す
e.printStackTrace();
}
}
3行目がファイルを読み込むためのデータ入力ストリームの準備で、5行目でバイナリデータを読み込んで、6行目でバイナリデータから文字列に変換しています。
そして、8行目でバイナリデータをそのままコンソール出力し、9行目でバイナリデータから文字列に変換したデータをコンソール出力しています。
9行目にコンソール出力されたものが、”この文章はサンプルです”であればきちんとバイナリファイルの読み込みに成功しているということになります。
実際に実行してみると以下のような結果になりました。
バイナリデータをそのままコンソール表示したものは意味不明な文字列になっていますが、バイナリデータから文字列に変換したものは、ファイルに出力した内容がきちんと表示されています。
つまり、きちんとバイナリデータを読み込んで、元のデータに復元する処理が成功しているということになります。
まとめ
今回は以下の2つのことを行いました。
- 文字列データをバイナリデータとしてファイルに保存
- 保存したファイルからバイナリデータを読み出し、文字列に変換して元の文字列が正しく復元できていることの確認
今回はバイナリファイルをreadAllBytes()で一括で読み込んでいますが、読み込むバイナリファイルのデータが大きい場合はここはひと工夫必要かもしれません。
バイナリデータとして保存し、バイナリデータとして読み込む処理は業務によっては使うケースも多いと考えられます。
そのため、今回お話ししたことはきちんと自分の技術の一つとして定着させ、必要に応じて使えるようにしておきたいものです。
今回の記事はここまでとなります。
また次の記事でお会いしましょう。