はじめに
Javaでソースコードを書いた際に躓いた話の備忘録を記載します。
デバッグにそれなりの時間をかけてしまったので、経験の記録をしておくことで次の学習の糧となるように残しておきたいと思います。
また、はじめのこの段階で申し上げておくが、筆者もJava初心者のため拙いソースコードとなっていることをご了承ください。
やりたかったこと:JavaでSQLを発行して取り出したデータをCSVファイルに書き出す
FileWriterクラスのWriteメソッドを使用して、SQLで取得したデータをローカルに格納してあるCSVファイルに記入します。(記述したSQL文は省略させていただきます。)
データベースから抽出した表(の一部)が以下となり、これをCSVファイルに書いていきます。
名前 | 性別 | 年齢 | 職歴 |
---|---|---|---|
tanaka | 男性 | 29 | 4年 |
suzuki | 男性 | 23 | 3ヵ月 |
yamamoto | 男性 | 26 | 1年 |
FileWriterクラスについて使い方がすでにいろんなところで紹介されているので、参考にさせてもらいました。具体的なページは本記事の後半で紹介します。
手本通りFileWriterクラスのコンストラクタを作成 ⇒ 抽出してきたデータをWriteメソッドで書き出し ⇒ それを取り出された行分ループ ⇒ 最後にファイルを閉じる。
という処理を書いてみました。記述したコードの一部を紹介します。(結論問題があったのはfileWriter.write( extractData.get(i).getAGE() );
の部分です。)
package xx_xxx;//今回のパッケージ
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;//使用する外部APIクラス群
public class FWSLBL {
public void extractCSV () {
//このインスタンス化は別ファイルでクラス定義しているため無視していただいてOKです。
//(一応紹介するが、SQLを実行して本記事冒頭の表をリスト形式で抽出してくる処理です。)
StudentxxxListDao xxx = new StudentxxxListDao();
List<StudentxxxListDto> extractData = dao.do_SQL();
//ファイルパスと改行の定数
final String FILE_PATH = "C:\\WorkSpace\\WriteFileSample.csv";
final String NEW_LINE = System.getProperty("line.separator");
try {
//ファイルクラスのコンストラクタ
File file = new File( FILE_PATH );
FileWriter fileWriter = new FileWriter(file);
if(extractData != null) {
//CSVのヘッダー
fileWriter.write("名前,性別,年齢,職歴,登録支店,受講講座");
fileWriter.write( NEW_LINE );
for(int i = 0; i < extractData.size() ; i++) {
fileWriter.write( extractData.get(i).getSTUDENT_NAME() );
fileWriter.write(",");
fileWriter.write( extractData.get(i).getGENDER() );
fileWriter.write(",");
// ※修正すべき部分↓
fileWriter.write( extractData.get(i).getAGE() );
// ※修正すべき部分↑
fileWriter.write(",");
fileWriter.write( extractData.get(i).getCAREER_MON() );
fileWriter.write( NEW_LINE );
}
fileWriter.close();
}else {
fileWriter.write("[INFO]該当の情報を取得できませんでした");
fileWriter.close();
}
//例外処理
}catch(IOException e) {
System.out.println(e);
}
}
}
起きた事象:出力結果に数値で定義した値が出ない
ソースコードを書き上げ、いざ実行してみたところ、、、、
問題なく処理は終わったようですが、CSVの中身を見たところ空白となっている個所がありました。
名前,性別,年齢,職歴
tanaka,男性, ,4年
suzuki,男性, ,3ヵ月
yamamoto,男性, ,1年
SQLで抽出した表形式のデータがコンマ区切りでファイルの中にすべて書かれていることを想定していましたが、想定と違っていたためデバッグ作業に取り掛かかりました。
結論:FileWriterクラスのwrite()メソッドは基本的に文字列しか扱えない
writeメソッドは基本的に文字列を書き出すためのものであるため、文字列型の数字を引数として渡してやれば、欲しかった結果になることが確認できました。
修正部分
fileWriter.write( extractData.get(i).getAGE() );
↓
fileWriter.write( Integer.toString(extractData.get(i).getAGE()) );
原因説明
エラーが吐き出されていない点が今回の厄介な点でした。
エラーになった場合、ソースコードの何行目にエラーがありそうだということがコンソール内のメッセージで教えてくれるのですが、エラーを吐かずに終わってしまうとどこに原因があるのかわからないため一つづつトレースする必要があります。
結果、writeメソッドは文字列型を扱うものですが、数値型の引数が渡された場合、引数の数字が書き込まれるのではなく、ASCIIコードでの文字が出力される仕様となっているようです。
今回の例でいうと渡された引数の数字に該当するASCIIコードが存在しなかったため、半角スペースが出力されたということだと思われます。
ASCIIコードは本記事のテーマとは逸れるので言及は避けることにします。
したがって、数字を書き出したい場合は引数の数字を文字列型に変換して渡してやる必要があります。
修正部分(再記載)
fileWriter.write( extractData.get(i).getAGE() );
↓
fileWriter.write( Integer.toString(extractData.get(i).getAGE()) );
再実行結果↓↓↓
名前,性別,年齢,職歴
tanaka,男性,29,4年
suzuki,男性,23,3ヵ月
yamamoto,男性,26,1年
参考リンク紹介
今回の課題でお世話になったリンクを載せておくので詳しく知りたい場合は参考にどうぞ。
↓参考リンク
おわりに
writeメソッド以外にもデータの型変換が必要なケースはたくさんあるかと思います。ですので基礎知識として頭に入れておけばエラーの原因特定に役立つ可能性があることを今回のことで学ばせていただ来ました。
プログラミング作業をしているとデバッグ作業は必ず発生してくるものととらえておくことが大前提であることを改めて実感しました。(当たり前のことだが。。。)
備忘録として本記事を執筆しましたが、読んだ方のプログラム学習の一助となれば幸いです。