Java写入文件重复追加问题:新增条目后旧内容重复写入
问题分析
你遇到的问题根源在于当前write()函数会覆盖整个文件并重新写入allItem列表中的所有条目,如果allItem列表存在重复条目(比如未从文件同步内容就重复添加,或列表未清空),就会导致文件内容重复。而你的需求是追加新条目到文件,但当前逻辑是重写整个文件。
解决方案
根据你的需求,提供两种可行方案:
方案1:直接追加单个新条目到文件末尾
这种方式无需重写整个文件,仅将新增条目追加到文件最后,彻底避免重复写入旧内容。
步骤1:新增追加条目函数
在Item类中添加专门的追加方法:
public static void appendItem(ItemList item) { try { // 开启文件追加模式(第二个参数true表示追加而非覆盖) PrintWriter writer = new PrintWriter(new FileWriter("item.txt", true)); writer.println(item.name); writer.println(item.category); writer.println(item.price); writer.println(); // 保留条目间的空行分隔 writer.close(); } catch (IOException ex) { System.out.println("Error in appendItem ..."); } }
步骤2:修改添加函数
将原添加函数中的Item.write()替换为调用新的追加函数,同时修正原类别判断的逻辑漏洞:
String cc1 = tf1.getText(); Customer found = Info.checkUserName(cc1); String b = y.getSelectedItem(); if (found == null) { if (b.equals("Others")) { String g = JOptionPane.showInputDialog("New Food Category"); if (category.contains(g)) { // 用contains判断类别是否已存在,修正原错误逻辑 JOptionPane.showMessageDialog(x, "Category exists"); } else { category.add(g); JOptionPane.showMessageDialog(x, "Food category added successfully!"); } } try { double d = Double.parseDouble(tf4.getText()); ItemList newItem = new ItemList(cc1, b, d); Item.allItem.add(newItem); Item.appendItem(newItem); // 替换原Item.write() JOptionPane.showMessageDialog(x, "Items added successfully!"); x.setVisible(false); Assignment.no2.y.setVisible(true); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(x, "Invalid price format!"); } }
方案2:重写整个文件但确保列表无重复条目
如果需要保持文件内容为完整的无重复条目列表,可以先从文件加载现有条目到allItem,添加新条目时检查重复,最后重写整个文件。
步骤1:添加读取文件函数
在Item类中添加读取文件加载条目的方法:
public static void readItems() { allItem.clear(); // 清空列表,避免重复加载旧内容 try { BufferedReader reader = new BufferedReader(new FileReader("item.txt")); String name; while ((name = reader.readLine()) != null) { String category = reader.readLine(); String priceStr = reader.readLine(); reader.readLine(); // 跳过条目间的空行 double price = Double.parseDouble(priceStr); allItem.add(new ItemList(name, category, price)); } reader.close(); } catch (IOException ex) { System.out.println("Error in readItems ..."); } }
步骤2:程序启动时加载条目
在程序初始化阶段(比如主类的main方法或窗口初始化方法)调用Item.readItems(),确保allItem列表与文件内容同步:
public static void main(String[] args) { Item.readItems(); // 其他初始化逻辑 }
步骤3:修改添加函数,检查条目重复
在添加新条目前,先检查是否已存在于allItem中:
String cc1 = tf1.getText(); Customer found = Info.checkUserName(cc1); String b = y.getSelectedItem(); if (found == null) { if (b.equals("Others")) { String g = JOptionPane.showInputDialog("New Food Category"); if (category.contains(g)) { JOptionPane.showMessageDialog(x, "Category exists"); } else { category.add(g); JOptionPane.showMessageDialog(x, "Food category added successfully!"); } } try { double d = Double.parseDouble(tf4.getText()); // 检查条目是否已存在(这里假设用name作为唯一标识) boolean itemExists = false; for (ItemList item : Item.allItem) { if (item.name.equals(cc1)) { itemExists = true; break; } } if (!itemExists) { Item.allItem.add(new ItemList(cc1, b, d)); Item.write(); // 调用原write函数重写整个文件 JOptionPane.showMessageDialog(x, "Items added successfully!"); x.setVisible(false); Assignment.no2.y.setVisible(true); } else { JOptionPane.showMessageDialog(x, "Item already exists!"); } } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(x, "Invalid price format!"); } }
内容的提问来源于stack exchange,提问作者Yee Fei Low
相关产品推荐
相关产品推荐

