写了一个小工具,遇到38G的大数据文件,出outofmemory错误,崩溃了。
改写了一下,没出错,效率还挺高,留作纪念。经验只有一条,千万不要把数据都读到内存里,否则神木也救不了。
打包用了fat jar插件,插到包成,超赞。
/**
* 機能:雇用保険のインタフェースファイルを統合統計用の格式に変換 <br>
* 入力ファイル:適用統計台帳ファイル <br>
* 出力ファイル:適用統計台帳事業所情報ファイル と 適用統計台帳被保険者情報ファイル
*
* @author btxiajunqing
*
*/
public class IFHenKan {
// ログ
private final static Logger log = Logger.getLogger(IFHenKan.class);
// 入力ファイル
private File inputFile = null;
// 一時ファイル名
private File tmpFile = null;
// カレンダー対象
private Calendar cpcalendar = new GregorianCalendar();
// データフォーマット
private SimpleDateFormat parseTime = new SimpleDateFormat("yyyyMMdd");
// 処理日を取得
private Calendar currentDate = null;
/**
* 適用統計台帳ファイルの変換を実行する
*
* @param file
* 入力ファイル
* @return 正常終了の場合:true 異常終了の場合:false
*/
public boolean execute(File file) {
// 入力データを取得
inputFile = file;
try {
// 台帳のデータをUTF-16BEで122バイト毎に読み込んで、出力チェックしてから一時出力ファイルに書き込み
createTempFile();
// 一時出力ファイルから一行づつデータを読み込み、解析して事業所情報ファイルと被保険者情報ファイルに出力
readFileByChars();
//一時出力ファイルを削除する
delTmpFile();
} catch (Exception e) {
log.error(e);
return false;
}
return true;
}
/**
* 一時出力ファイルを一行づつ読み込み、解析して結果ファイルを作成します。 <br>
* 入力ファイル:一時出力ファイル <br>
* 出力ファイル:適用統計台帳事業所情報ファイル と 適用統計台帳被保険者情報ファイル
*
* @throws Exception
*/
public void readFileByChars() throws Exception {
// 事業所情報ファイル
File file_jigyosyo = null;
// 被保険者情報ファイル
File file_hihokensha = null;
// 読み込みファイルのオブジェクト
BufferedReader reader = null;
// 事業所情報ファイルを書き込む用ストリーム
BufferedWriter writer_jigyosyo = null;
// 被保険者情報ファイルを書き込む用ストリーム
BufferedWriter writer_hihokensha = null;
// 事業所情報の項目の配列
String[] arr_output_jigyosyo = new String[Const.CNT_JIGYOSYO];
// 被保険者情報の項目の配列
String[] arr_output_hihokensha = new String[Const.CNT_HIHOKENSHA];
// 一レコードを格納用オブジェクト
String line = "";
StringBuilder temp = new StringBuilder(Const.LEN_RECORD_TEKIYO);
// 事業所情報件数
long cnt_jigyosyo = 0L;
// 被保険者情報件数
long cnt_hihokensha = 0L;
try {
// 事業所情報ファイルのフルパスを取得
file_jigyosyo = new File(inputFile.getParent() + File.separator
+ Const.FILE_JIGYOSHO);
// 被保険者情報のフルパスを取得
file_hihokensha = new File(inputFile.getParent() + File.separator
+ Const.FILE_HIHOKENSHA);
// 事業所情報ファイルを作成
file_jigyosyo.createNewFile();
// 被保険者情報ファイルを作成
file_hihokensha.createNewFile();
// 入力ファイルを読み込み
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(tmpFile), "UTF-8"));
// 事業所情報ファイル
writer_jigyosyo = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file_jigyosyo), "UTF-8"));
// 被保険者情報ファイル
writer_hihokensha = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file_hihokensha), "UTF-8"));
// 一行づづ読み込み、項目を解析する
while ((line = reader.readLine()) != null) {
// レコードのオブジェクトを初期化
if (temp.length() != 0) {
temp.delete(0, temp.length());
}
// レコードのデータを設定
temp.append(line);
// 事業所情報の場合(レコード種別コード=0100)
if (Const.RECORD_TYPE_JIGYOSYO.equals(temp.substring(28, 32))) {
// 事業所番号
int start = 0;
int end = start + Const.LEN_ITEM_10;
arr_output_jigyosyo[0] = format(temp.substring(start, end),
Const.LEN_ITEM_10);
// 設置処理日
start = end + Const.LEN_ITEM_10 + Const.LEN_ITEM_8
+ Const.LEN_ITEM_4 + Const.LEN_ITEM_8;
end = start + Const.LEN_ITEM_8;
arr_output_jigyosyo[1] = format(temp.substring(start, end),
Const.LEN_ITEM_8);
// 事業所管轄
start = end;
end = start + Const.LEN_ITEM_1;
arr_output_jigyosyo[2] = format(temp.substring(start, end),
Const.LEN_ITEM_1);
// 廃止処理日
start = end + Const.LEN_ITEM_2 + Const.LEN_ITEM_1
+ Const.LEN_ITEM_1 + Const.LEN_ITEM_1
+ Const.LEN_ITEM_2 + Const.LEN_ITEM_8;<