列サイズが値によって可変になる固定長ファイル(以後列サイズ可変の固定長)とtsvファイルとの相互変換ロジックです
例えば↓のようなファイル
aaa bbb ccc
a bbbbb c
aa bbbb cc
通常のtsvだとエディタで開いたときにガタガタになるので、固定長にしたい。
しかし列サイズが不定だ、という場合に使います。
変換ロジック
final static String SEPARATOR = "(\t| )";
final static String NEW_LINE = "\n";
/**
* TSV⇒列サイズ可変の固定長への変換
* @throws UnsupportedEncodingException
*/
public String Tsv2FixedLengthConv(String inStr) {
inStr = FixedLength2TsvConv(inStr);
//配列への変換
String[] lineList = inStr.split(NEW_LINE);
String[][] tsv = new String[lineList.length][];
//for( String line : lineList ) {
for( int i=0;i<lineList.length;i++) {
tsv[i] = lineList[i].split(SEPARATOR);
}
//固定長の幅取得
Map<Integer, Integer> maxLengthMap = new HashMap<>();
try {
for( int y=0;y<tsv.length;y++) {
for( int x=0;x<tsv[y].length;x++) {
int len;
len = tsv[y][x].getBytes("Shift_jis").length;
//len = tsv[y][x].getBytes("iso-2022-jp").length;
if( maxLengthMap.containsKey(x) ){
int oldLen = maxLengthMap.get(x);
if( oldLen < len ) {
maxLengthMap.put(x, len);
}
}else {
maxLengthMap.put(x, len);
}
}
}
} catch (UnsupportedEncodingException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
//固定長への変換
StringBuilder fixedLenStr = new StringBuilder();
try {
for( int y=0;y<tsv.length;y++) {
for( int x=0;x<tsv[y].length;x++) {
int len = maxLengthMap.get(x);
//String s = String.format("%-"+ (len+1) +"s", tsv[y][x] );
int valLength = tsv[y][x].getBytes("Shift_jis").length;
String s = tsv[y][x].replaceAll("$", StringUtils.repeat(" ", len-valLength+1) );
fixedLenStr.append(s);
}
fixedLenStr.append(NEW_LINE);
}
} catch (UnsupportedEncodingException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
return fixedLenStr.toString();
}
/**
* 列サイズ可変の固定長⇒TSVへの変換
*/
public String FixedLength2TsvConv(String inStr) {
inStr = inStr.replaceAll("(\\t| )+", "\t");
inStr = inStr.replaceAll("(\\t| )+"+NEW_LINE, NEW_LINE);
return inStr;
}