Java 实现定长报文模拟器(支持配置文件 默认值)
在金融、证券、工业控制等场景,经常使用定长报文(Fixed-Length Message)来保证高效、稳定的数据传输。本文介绍如何用 Java 读取配置文件,根据字段偏移量生成定长报文,并支持默认值与自动填充。
1. 需求分析
目标
-
支持字段偏移量配置(从
resources/packet_simulate.txt
读取)。 -
支持默认值,如未提供,则自动填充随机值。
-
超长截断,不足补空格,确保格式对齐。
-
生成完整的定长报文。
配置文件格式 (packet_simulate.txt
)
每行定义一个字段:
字段索引\t字段名称\t起始位置\t长度\t默认值(可选)
示例:
1\t交易码\t0\t6\tTRADE
2\t银行卡号\t6\t16\t6225881234567890
3\t交易金额\t22\t10\t10000
4\t交易日期\t32\t8\t20240314
5\t授权码\t40\t6\t
授权码
未提供默认值,将自动生成随机值。\t 表示制表符,比如从excel编辑数据后粘贴到txt文件会带有制表符
2. 代码实现
2.1 解析配置文件
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class FixedLengthMessageSimulator {
private static final String CONFIG_PATH = "resources/packet_simulate.txt";
private static final Random RANDOM = new Random();
public static List<FieldDefinition> loadFieldDefinitions() throws IOException {
List<FieldDefinition> fields = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(CONFIG_PATH))) {
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split("\\t");
if (parts.length < 4) continue;
int index = Integer.parseInt(parts[0]);
String fieldName = parts[1];
int start = Integer.parseInt(parts[2]);
int length = Integer.parseInt(parts[3]);
String defaultValue = (parts.length > 4) ? parts[4] : "";
fields.add(new FieldDefinition(index, fieldName, start, length, defaultValue));
}
}
return fields;
}
}
2.2 生成定长报文
public static String generateMessage(List<FieldDefinition> fields) {
int totalLength = fields.get(fields.size() - 1).startPosition + fields.get(fields.size() - 1).length;
byte[] message = new byte[totalLength];
for (FieldDefinition field : fields) {
int start = field.startPosition;
int length = field.length;
String value = field.defaultValue.isEmpty() ? generateRandomString(length) : field.defaultValue;
value = fixLength(value, length);
System.arraycopy(value.getBytes(StandardCharsets.UTF_8), 0, message, start, length);
}
return new String(message, StandardCharsets.UTF_8);
}
2.3 处理超长 & 填充空格
private static String generateRandomString(int length) {
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append(chars.charAt(RANDOM.nextInt(chars.length())));
}
return fixLength(sb.toString(), length);
}
private static String fixLength(String value, int length) {
return value.length() > length ? value.substring(0, length) : String.format("%-" + length + "s", value);
}
2.4 运行程序
public static void main(String[] args) {
try {
List<FieldDefinition> fields = loadFieldDefinitions();
String message = generateMessage(fields);
System.out.println("生成的报文: [" + message + "]");
} catch (IOException e) {
System.err.println("读取配置文件失败: " + e.getMessage());
}
}
3. 示例输出
生成的报文: [TRADE622588123456789010000 20240314V5X9Z2]
-
TRADE
(6位) -
6225881234567890
(16位) -
10000
(10位,补空格) -
20240314
(8位) -
V5X9Z2
(6位,自动填充随机值)
4. 代码特点 & 优势
✅ 支持配置文件,按字段顺序、名称、偏移量、长度、默认值读取。 ✅ 支持默认值,如未提供则自动生成随机字符串。 ✅ 超长截断 & 不足补空格,确保格式符合规范。 ✅ 解析 & 生成高效,适用于大批量报文生成。 ✅ 可扩展,可支持 JSON 配置、变长字段等。
5. 适用场景
📌 银行清算报文(ISO 8583、SWIFT) 📌 证券交易(FIX 协议) 📌 工业控制 & 物联网 📌 航空/铁路票务 📌 政府数据交换