ファイルインターフェースがいまだに最善である理由
一言でいうと
ファイル連携が生き残った理由は、大量・明確な境界・簡単な再処理であり、その代わり、位置がそのまま意味になる固定長と、書き終える前に持っていかれる問題を、自分で扱う必要があります。
なぜ今でもファイルなのか
RESTやキューがあるのに、なぜファイルでやり取りするのか。理由は明確です。
- 大量処理に強いです。100万件を1件ずつの呼び出しで送ると数時間ですが、ファイル1つなら数分です。
- 境界が明確です。「8月1日付の売上ファイル」という単位は、業務担当者にとって自然です。件数と合計を、きっちり突合できます。
- 再処理が簡単です。ファイルをもう一度入れればよいのです。キューの再処理よりも直感的です。
- 相手がそれしかできません。20年前のシステム、対外機関、銀行のEDI。「RESTで送ってください」が通用しません。
そのため、SIの現場で、ファイル連携はなくなりません。むしろ、バッチの夜間作業の大きな柱は、今もファイルです。
固定長電文: 位置がそのまま意味です
20260801HONG 0000012500Y
| || || ||
1-8 9-28 29-38 39
일자 고객명(20) 금액(10) 여부(1)
このコードブロックの韓国語は、下の行で、各位置の項目名を順に、日付、顧客名(20)、金額(10)、フラグ(1)と示しています。
レイアウト定義書には、開始位置、長さ、型、寄せ、埋め文字がある必要があります。
| 項目 | 慣行 |
|---|---|
| 文字フィールド | 左寄せ、右側を空白で埋めます |
| 数値フィールド | 右寄せ、左側を0で埋めます |
| 金額 | 小数点なしの整数で、桁数を定義書に明記します |
| 負数 | 最後の桁に符号を重ねるか、別の符号フィールドにします |
| 日付 | YYYYMMDDの8桁 |
ハングルが入ると、問題が始まります。「長さ20」が20バイトなのか20文字なのかによって、まったく別のファイルになります。EUC-KRならハングル1文字が2バイト、UTF-8なら3バイトです。そして、固定長は、1バイトずれるだけで、その後ろがすべて壊れます。
そのため、韓国の対外連携では、EUC-KR(またはCP949)が今も生きています。ハングルが2バイトできっちり収まり、桁数の計算が楽だからです。受け取ったファイルが文字化けして見えたら、まずエンコーディングを疑って変換してみます。
iconv -f EUC-KR -t UTF-8 SALES_20260801.dat > SALES_utf8.dat
ヘッダーとトレーラー: ファイル自身の自己検証
よく設計されたファイルインターフェースには、ヘッダーとトレーラーがあります。
H20260801SALES 0001 ← 헤더: 구분, 일자, 업무, 파일순번
D20260801HONG 0000012500 ← 데이터
D20260801KIM 0000030000
T0000000002000000042500 ← 트레일러: 건수, 금액 합계
このコードブロックの韓国語コメントは、順に、ヘッダー(区分、日付、業務、ファイル連番)、データ、トレーラー(件数、金額合計)を意味します。
トレーラーが存在する理由はただ1つです。ファイルが完全に到着したことを、自ら証明するためです。
- データの件数 == トレーラーの件数か
- データの金額合計 == トレーラーの合計か
送信中に切れた、途中で1行が失われた、エンコーディング変換中に壊れた、といった場合は、この検査で引っかかります。この検証をしないと、半分しか届いていないファイルを正常に処理します。そして、その事実は、月末の締めのときに「数字が合わない」として発見されます。
トレーラーの検証は、処理の前に行う必要があります。処理中に行うと、すでに半分が反映された状態になります。
完了フラグ: 書き終える前に持っていかれる問題
FTPでファイルがアップロードされている最中に、バッチがそのファイルを持っていったら、どうなるでしょうか。半分のファイルを処理します。トレーラーの検証があれば引っかかりますが、なければそのまま入ります。
標準的な規約は、完了フラグファイルです。
SALES_20260801.dat ← 데이터 (전송 중일 수 있음)
SALES_20260801.dat.ok ← 이 파일이 생겨야 처리 대상
このコードブロックの韓国語コメントは、順に、データ(送信中の可能性がある)と、このファイルが作られて初めて処理対象になる、という意味です。
送信側がデータをすべて送り終えたあとに、空の.okファイルを作ります。受信側は、.okがあるものだけを処理します。単純ですが、非常に効果的です。
定義書に必ず明記する必要があります。「フラグファイル規約」が片方にしかないと、相手はただデータだけをアップロードし、こちらのバッチは永遠に何も処理しません。そして、何のエラーも出ません。静かに何もしないことが、最も遅く発見されます。
ファイル名の規則もインターフェースです
<업무코드>_<기준일자>_<순번>.<확장자>
SALES_20260801_001.dat
(山括弧の中の韓国語はプレースホルダーで、順に業務コード、基準日、連番、拡張子です。)
- 基準日がファイル名にあって初めて、再処理するファイルを特定できます
- 連番があって初めて、1日に複数回届く場合を区別できます
- ファイル名の規則がないと、
sales.txtが毎日上書きされ、昨日のものを見つけられません
処理後の保管
処理したファイルは削除せずに保管します。
/data/if/archive/20260801/SALES_20260801_001.dat.gz
- 日付別のディレクトリに分けて初めて、1つのディレクトリにファイルが数十万個溜まるのを防げます
- 圧縮します。テキストファイルは、たいてい80–90%小さくなります
- 保管期間を定義書に明記します。無期限の保管は、ディスクが満杯になる障害として返ってきます
保管が必要な理由は、再処理と紛争のためです。「その日にこちらが送ったのは12,000件ですが」という言葉に答えるには、原本が必要です。
突合(Reconciliation): ファイル連携の最後の段階
ファイルを処理したら終わりではありません。両側の数字が合っているかを確認する必要があります。
| 突合項目 | 方法 |
|---|---|
| 件数 | 送信件数 == 受信の処理件数 + エラー件数 |
| 金額合計 | 送信合計 == 受信合計 |
| キー集合 | 送信キー一覧 - 受信キー一覧 = 空集合 |
件数と合計だけが合えば安心しやすいですが、1件が抜けて別の1件が2回入っても、件数は合います。そのため、金額合計も一緒に見て、正確性が重要なインターフェースは、キー集合まで比較します。
突合の結果はファイルとして残します。そして、不一致があれば、自動的に担当者に通知されるようにします。突合の結果を人が毎日開いて見る方式は、忙しい日にスキップされ、スキップしたその日に問題があります。
現場での姿
ファイル連携で起きる事故は、種類が決まっています。
- 半端なファイルを処理しました。相手がまだ書き込んでいる最中に、こちらが持っていってしまったのです。そのため、完了フラグ(
.ok)を一緒に書き、フラグがあるファイルだけを拾います。このルールがないと、「ある日は件数が少なく入ってくる」という再現しないバグになります。 - エンコーディングが変わりました。EUC-KRで来ていたファイルが、ある日UTF-8で来ます。固定長では、ハングルのバイト長が変わるので、その後ろのフィールドがすべてずれます。画面には、名前が文字化けしたまま、金額は見当違いの値で入ります。
- トレーラーを見ていませんでした。ファイル自身が件数と合計を持っているのに、それを突き合わせないと、送信中に切れたファイルをそのままロードしても、誰も気づきません。
3つとも、ファイルを読む前に、ファイルを信頼できるかを確認する手続きがないために起きます。そのため、ファイル連携の最初のステップは、パースではなく検証です。