You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX读取XML到TextField并写入XML时文件为空问题求助

问题分析与解决方案

核心问题点

  • 重复读写覆盖文件:saveNewValues()循环遍历HashMap时,每次都重新打开原文件和目标文件,导致目标文件被反复覆盖,最终仅保留最后一次循环的写入内容(甚至为空)。
  • 丢失原文件结构:仅写入匹配到的条目内容,原文件中的XML声明、注释、未修改标签等行完全被丢弃,生成的文件结构缺失。
  • 流未正确刷新/关闭:BufferedWriter未调用flush()和close(),内存中的内容无法写入磁盘。

修正后的saveNewValues()方法

public void saveNewValues() {
    if (readXml == null) {
        System.out.println("请先读取XML文件");
        return;
    }

    BufferedReader br = null;
    BufferedWriter bw = null;

    try {
        br = new BufferedReader(new FileReader(readXml));
        bw = new BufferedWriter(new FileWriter("C:\\Users\\abcdef\\tmpFile.xml"));

        String text;
        while ((text = br.readLine()) != null) {
            boolean isModified = false;

            // 处理<comment>标签
            if (text.contains("<comment>") && !(text.startsWith("<!--"))) {
                String variableName = text.substring(text.indexOf("<") + 1, text.indexOf(">"));
                TextField txtField = hashMapXml.get(variableName);
                if (txtField != null) {
                    // 替换标签内的内容,保留标签结构
                    int start = text.indexOf(">") + 1;
                    int end = text.indexOf("<", start);
                    String newText = text.substring(0, start) + txtField.getText() + text.substring(end);
                    bw.write(newText);
                    isModified = true;
                }
            }
            // 处理<entry>标签
            else if (text.contains("<entry") && !(text.startsWith("<!--"))) {
                String variableName = text.substring(text.indexOf("=") + 2, text.indexOf("\"", text.indexOf("\"") + 1));
                TextField txtField = hashMapXml.get(variableName);
                if (txtField != null) {
                    // 替换标签内的内容,保留标签结构
                    int start = text.indexOf(">") + 1;
                    int end = text.indexOf("<", start);
                    String newText = text.substring(0, start) + txtField.getText() + text.substring(end);
                    bw.write(newText);
                    isModified = true;
                }
            }

            // 未修改的行直接写入
            if (!isModified) {
                bw.write(text);
            }
            bw.newLine(); // 保留原文件的换行格式
        }

        bw.flush(); // 强制将内存内容写入磁盘
        System.out.println("文件保存成功");

        // 若需直接覆盖原XML文件,可添加以下代码(需导入java.nio.file相关类)
        // Files.copy(Paths.get("C:\\Users\\abcdef\\tmpFile.xml"), Paths.get(readXml.getAbsolutePath()), StandardCopyOption.REPLACE_EXISTING);

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 确保流资源被释放
        try {
            if (br != null) br.close();
            if (bw != null) bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

关键改进说明

  1. 单次读写流程:仅读取一次原文件,逐行处理并写入目标文件,避免重复覆盖。
  2. 完整保留XML结构:仅替换标签内的内容,保留原文件的所有非修改行和标签格式。
  3. 流资源正确处理:在finally块中关闭读写流,写入完成后调用flush()确保内容落地。
  4. 空指针防护:先检查是否已读取XML文件,避免空指针异常。
  5. 可选原文件覆盖:若需要直接替换原文件,可启用注释中的Files.copy逻辑。

额外优化建议

  • 改用标准XML解析库:当前通过字符串截取处理XML易出错(如标签格式变化、嵌套场景),建议使用JAXB、DOM4J等专业XML解析工具提升健壮性。
  • 路径可配置化:目标文件路径硬编码在代码中,建议改为通过FileChooser让用户选择保存路径,或配置到外部文件中。

内容的提问来源于stack exchange,提问作者Katapa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 16:45:47