如何替换特定section行指定位置的Oldvalue为数据库查询的NewValue?
固定位置文本替换结合数据库查询完整解决方案
一、场景与需求
输入文件内容
0000001HL26110650059147 TEST- TEST 0000002HL34110FON202212217835294783529 20221221123000 650059147 0000003HL34120FON20221221783529BLE50000395 13626142 0000004HL34120FON20221221783529BLE50000395 13626143
字段规则
- 0-7位:sequence(序号)
- 11-14位:section(段标识)
核心需求
当section等于120时,将该行47-67位的Oldvalue替换为数据库查询得到的NewValue;其他行保持不变,支持多行匹配。
数据库查询语句
select NewValue from myTable where Oldvalue = 'Oldvalue'
替换后输出示例
0000001HL26110650059147 TEST- TEST 0000002HL34110FON202212217835294783529 20221221123000 650059147 0000003HL34120FON20221221783529BLE50000395 NewValue1 0000004HL34120FON20221221783529BLE50000395 NewValue2
二、现有代码不足
你提供的代码仅完成了文件读取和符合条件行的Oldvalue提取,缺少:
- 数据库连接与查询逻辑
- 文本替换逻辑
- 处理后结果的写入逻辑
三、完整解决方案代码
以下Java代码包含完整的文件读写、数据库查询、文本替换逻辑,同时优化了查询性能(批量收集Oldvalue后一次性查询,减少数据库交互):
import java.io.*; import java.sql.*; import java.util.*; public class FileValueReplacer { // 数据库连接配置,根据实际情况修改 private static final String DB_URL = "jdbc:mysql://localhost:3306/your_db_name"; private static final String DB_USER = "your_username"; private static final String DB_PASSWORD = "your_password"; public static void main(String[] args) { String inputFilePath = "C:/Users/20230309.in"; String outputFilePath = "C:/Users/20230309_out.in"; List<String> lines = readFile(inputFilePath); if (lines == null || lines.isEmpty()) { System.out.println("无有效文件内容"); return; } // 1. 收集所有需要查询的Oldvalue Map<String, String> oldToNewValueMap = new HashMap<>(); for (String line : lines) { // 校验行长度是否足够,避免数组越界 if (line.length() >= 67 && line.length() >= 14) { String section = line.substring(11, 14).trim(); if ("120".equals(section)) { String oldValue = line.substring(47, 67).trim(); oldToNewValueMap.put(oldValue, null); // 先占位,后续填充 } } } // 2. 批量查询数据库,获取NewValue映射 if (!oldToNewValueMap.isEmpty()) { fillNewValues(oldToNewValueMap); } // 3. 处理每行内容,替换对应值 List<String> processedLines = new ArrayList<>(); for (String line : lines) { boolean isTargetLine = false; if (line.length() >= 67 && line.length() >= 14) { String section = line.substring(11, 14).trim(); if ("120".equals(section)) { String oldValue = line.substring(47, 67).trim(); String newValue = oldToNewValueMap.getOrDefault(oldValue, oldValue); // 查不到则保留原值 // 拼接替换后的字符串:0-46位 + 补全长度的newValue + 67位之后的内容 String prefix = line.substring(0, 47); String suffix = line.substring(67); // 确保newValue长度和原位置一致(20位),不足补空格,超过截断 String formattedNewValue = String.format("%-20s", newValue).substring(0, 20); String newLine = prefix + formattedNewValue + suffix; processedLines.add(newLine); isTargetLine = true; } } if (!isTargetLine) { processedLines.add(line); } } // 4. 写入输出文件 writeFile(outputFilePath, processedLines); System.out.println("处理完成,输出文件:" + outputFilePath); } /** * 读取文件内容到列表 */ private static List<String> readFile(String filePath) { List<String> lines = new ArrayList<>(); try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { String line; while ((line = br.readLine()) != null) { lines.add(line); } } catch (IOException e) { System.out.println("读取文件失败:" + e.getMessage()); e.printStackTrace(); return null; } return lines; } /** * 批量查询数据库,填充oldValue到newValue的映射 */ private static void fillNewValues(Map<String, String> oldToNewValueMap) { String placeholders = String.join(",", Collections.nCopies(oldToNewValueMap.size(), "?")); String sql = "select Oldvalue, NewValue from myTable where Oldvalue in (" + placeholders + ")"; try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD); PreparedStatement pstmt = conn.prepareStatement(sql)) { // 设置参数 int idx = 1; for (String oldValue : oldToNewValueMap.keySet()) { pstmt.setString(idx++, oldValue); } // 执行查询 try (ResultSet rs = pstmt.executeQuery()) { while (rs.next()) { String oldVal = rs.getString("Oldvalue"); String newVal = rs.getString("NewValue"); oldToNewValueMap.put(oldVal, newVal); } } } catch (SQLException e) { System.out.println("数据库查询失败:" + e.getMessage()); e.printStackTrace(); } } /** * 将处理后的内容写入文件 */ private static void writeFile(String filePath, List<String> lines) { try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) { for (String line : lines) { bw.write(line); bw.newLine(); } } catch (IOException e) { System.out.println("写入文件失败:" + e.getMessage()); e.printStackTrace(); } } }
代码说明
- 数据库配置:修改
DB_URL、DB_USER、DB_PASSWORD为你的实际数据库信息 - 批量查询优化:先收集所有需要替换的Oldvalue,一次性查询数据库,避免每行发起一次查询,提升性能
- 字符串处理:替换时保持原位置的长度(20位),不足补空格,超过截断,保证文件格式一致性
- 资源管理:使用try-with-resources自动关闭文件流和数据库连接,避免资源泄漏
- 异常处理:针对文件读写、数据库操作添加了异常捕获与提示
内容的提问来源于stack exchange,提问作者Java BEE
相关产品推荐
相关产品推荐

