feat: UNSTRING解析增强 + 跨FD数值统一 + 文件I/O模块

This commit is contained in:
hangshuo652
2026-06-30 22:14:47 +08:00
parent 2f61ad7f1a
commit b3d1643220
7 changed files with 980 additions and 14 deletions
+54 -2
View File
@@ -1,8 +1,13 @@
"""输出层:JSON输出(按文件分组入出力 + 工作存储区分)"""
import json
import logging
from pathlib import Path
from . import file_io
logger = logging.getLogger(__name__)
_INVERSE_OP = {'>': '<=', '<': '>=', '=': '<>', '>=': '<', '<=': '>'}
@@ -120,7 +125,7 @@ def output_json(records, outpath, roles=None, fd_fields=None, field_to_fd=None,
def output_input_files(records, outdir, stem, roles, fd_fields, field_to_fd, open_dir,
term_types=None):
term_types=None, data_fields=None, select_info=None):
term_types = term_types or ['normal'] * len(records)
input_fds = {}
for fd_name, fds_set in fd_fields.items():
@@ -137,7 +142,8 @@ def output_input_files(records, outdir, stem, roles, fd_fields, field_to_fd, ope
outdir.mkdir(parents=True, exist_ok=True)
for fd_name, fds_set in input_fds.items():
fd_items = list(input_fds.items())
for fd_idx, (fd_name, fds_set) in enumerate(fd_items):
normals = []
abends = []
direction = (open_dir or {}).get(fd_name, '')
@@ -155,7 +161,53 @@ def output_input_files(records, outdir, stem, roles, fd_fields, field_to_fd, ope
else:
normals.append(fd_rec)
# 丢弃次要 FD 的最后 2 条记录,触发 EOF/不匹配路径
if fd_idx > 0 and normals:
normals = normals[:-2]
if normals:
_write_json(normals, outdir / f'{stem}_{fd_name}.json')
if abends:
_write_json(abends, outdir / f'{stem}_abend_{fd_name}.json')
if data_fields and select_info and normals:
assign_name = select_info.get(fd_name, {}).get('assign')
if assign_name:
bin_path = outdir / assign_name
name_to_field = {
f['name']: f for f in data_fields
if not f.get('is_88') and not f.get('is_filler')
and f.get('pic')
}
field_dicts = []
seen = set()
for fname in fds_set:
if fname in seen:
continue
seen.add(fname)
fd = name_to_field.get(fname)
if fd:
field_dicts.append(fd)
if field_dicts:
offsets = []
offset = 0
for fd in field_dicts:
offsets.append(offset)
offset += file_io.get_storage_length(fd)
rec_len = offset
if rec_len > 0:
with open(bin_path, 'wb') as f:
for rec in normals:
buf = bytearray(rec_len)
for fd, off in zip(field_dicts, offsets):
val = rec.get(fd['name'], '')
try:
packed = file_io.pack_value(val, fd)
except Exception as e:
logger.debug(f"pack_value failed for {fd['name']}: {e}")
slen = file_io.get_storage_length(fd)
packed = b'\x00' * slen
end = min(off + len(packed), rec_len)
buf[off:end] = packed[:end - off]
f.write(bytes(buf))
logger.info(f" wrote {len(normals)} binary records to {bin_path}")