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(); } } }
关键改进说明
- 单次读写流程:仅读取一次原文件,逐行处理并写入目标文件,避免重复覆盖。
- 完整保留XML结构:仅替换标签内的内容,保留原文件的所有非修改行和标签格式。
- 流资源正确处理:在
finally块中关闭读写流,写入完成后调用flush()确保内容落地。 - 空指针防护:先检查是否已读取XML文件,避免空指针异常。
- 可选原文件覆盖:若需要直接替换原文件,可启用注释中的
Files.copy逻辑。
额外优化建议
- 改用标准XML解析库:当前通过字符串截取处理XML易出错(如标签格式变化、嵌套场景),建议使用JAXB、DOM4J等专业XML解析工具提升健壮性。
- 路径可配置化:目标文件路径硬编码在代码中,建议改为通过FileChooser让用户选择保存路径,或配置到外部文件中。
内容的提问来源于stack exchange,提问作者Katapa
相关产品推荐
相关产品推荐

