package util;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* セパレーテッドバリューファイル
*/
public class SvFile {
/** デリミタ */
private String delm = null;
/** SV行データリスト */
List<List<String>> svLineList = null;
public List<List<String>> getSvLineList() {
return svLineList;
}
public void setSvLineList(List<List<String>> svLineList) {
this.svLineList = svLineList;
}
/**
* コンストラクタ
*/
public SvFile() {
}
/**
* 指定されたファイルのデータを読み込みます。デリミタを指定しないコンストラクタの場合、デリミタはタブとなります。
*
* @param fileName
* ファイル名
* @throws IOException
*/
public void loadFile(String fileName) throws IOException {
// SVファイルをロードする
loadFile(fileName, "\t", false);
}
/**
* デリミタを区切り文字として、指定されたファイルのデータを読み込みます。最初の行は読み飛ばしません。
*
* @param fileName
* ファイル名
* @param delm
* デリミタ
* @throws IOException
*/
public void loadFile(String fileName, String delm) throws IOException {
// SVファイルをロードする
loadFile(fileName, delm, false);
}
/**
* デリミタを区切り文字として、指定されたファイルのデータを読み込みます。
*
* @param fileName
* ファイル名
* @param delm
* デリミタ
* @param skipFirstLine
* 最初の行を読み飛ばす場合はtrue、そうでなければfalse
* @throws IOException
*/
private void loadFile(String fileName, String delm, boolean skipFirstLine)
throws IOException {
// デリミタを記憶しておく
this.delm = delm;
// SV行データリストを初期化する
setSvLineList(new ArrayList<List<String>>());
// ファイルを開く
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(new File(fileName)));
// 最初の行をスキップする設定の場合は、読み捨てを行う
String line = "";
if (skipFirstLine) {
line = br.readLine();
}
// 全ての行を処理するまでループ
while ((line = br.readLine()) != null) {
// SV行のデータをロードする
loadLine(line);
}
// 最後に必ずファイルを閉じる
} finally {
if (br != null) {
br.close();
}
}
}
/**
* SVファイルの行データをロードします。SV値は改行なし、ダブルクオートによるエスケープもなしと前提します。
*
* @param line
* 行データ
*/
private void loadLine(String line) {
// 文字列をスプリッタで分割する
String[] svValArray = line.split(delm);
// 行データ内の全てのSV値を処理するまでループ
List<String> svValList = new ArrayList<String>();
for (String svVal : svValArray) {
// 【重要!】null値を検出した場合は空文字列を設定する
if (svVal.equals("(null)")) {
svValList.add("");
}
// 【重要!】SV値はダブルクオートで囲むルールとする
else if (svVal.length() == "".length()) {
svValList.add("");
} else if (svVal.startsWith("\"") && svVal.endsWith("\"")) {
svValList.add(svVal.substring(1, (svVal.length() - 1)));
}
}
// リストに行データを追加する
getSvLineList().add(svValList);
}
/**
* 引数で指定されたSV行データリストで既存のデータを上書きします。
*
* @param fileName
* ファイル名
* @param delm
* デリミタ
* @param svLineList
* SV行データリスト
* @throws IOException
*/
public void save(String fileName, List<List<String>> svLineList)
throws IOException {
// セーブする
save(fileName, "\t", svLineList);
}
/**
* 引数で指定されたSV行データリストで既存のデータを上書きします。
*
* @param fileName
* ファイル名
* @param delm
* デリミタ
* @param svLineList
* SV行データリスト
* @throws IOException
*/
public void save(String fileName, String delm, List<List<String>> svLineList)
throws IOException {
BufferedWriter bw = null;
try {
// ファイルを書き込み用に開く
bw = new BufferedWriter(new FileWriter(new File(fileName)));
// 全ての行データを処理するまでループ
for (List<String> svLine : svLineList) {
// SV行データの各カラムをデリミタで接続する
StringBuffer sb = new StringBuffer("");
for (String column : svLine) {
// 1つ以上のカラムをSV行に設定している場合は、区切り文字を入れる
if (sb.length() > 0) {
sb.append(delm);
}
// 【重要!】空文字列はnull値として記録する
if (column == null || column.length() == 0) {
sb.append("(null)");
}
// 【重要!】SV値はダブルクオートで囲むルールとする
else {
sb.append("\"" + column + "\"");
}
}
// ファイルに書き込みを行い、最後に改行を入れる
bw.write(sb.toString());
bw.newLine();
}
} finally {
// ファイルをクローズする
bw.close();
}
}
}