
在java中,当使用filewriter写入文件时,一个常见的陷阱是其默认行为会覆盖文件中的所有现有内容。这意味着,如果每次程序运行时都创建一个新的filewriter实例来写入同一个文件,那么之前保存的数据将会丢失。例如,以下代码片段展示了这种问题:
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Scanner;
public class NoteApp {
private ArrayList<String> memory = new ArrayList<>();
private static final String FILENAME = "notes.data";
// 错误的写入方法:每次都覆盖文件
public void fileHandlingWrong() {
try {
// 默认构造函数会覆盖文件内容
FileWriter fWriter = new FileWriter(FILENAME);
for (String note : memory) {
fWriter.write(note + '\n');
}
fWriter.close();
} catch (IOException e) {
System.err.println("写入文件时发生错误: " + e.getMessage());
}
}
public void createNote() {
Scanner insertNote = new Scanner(System.in);
LocalDate todayDate = LocalDate.now();
LocalTime nowTime = LocalTime.now();
String timeFormat = nowTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM));
String dateTime = todayDate.toString() + " at " + timeFormat;
System.out.println("\nEnter a note");
System.out.print("> ");
String note = insertNote.nextLine();
if (note == null || note.trim().isEmpty()) {
System.out.println("无效输入!请重试");
} else {
memory.add(note + " /" + dateTime);
fileHandlingWrong(); // 调用错误的写入方法
System.out.println("笔记已保存!\n");
}
}
public static void main(String[] args) {
NoteApp app = new NoteApp();
app.createNote(); // 第一次运行,输入 "Hello"
// 假设程序在此退出并重新运行
// app.createNote(); // 第二次运行,输入 "World","Hello" 将被覆盖
}
}上述fileHandlingWrong()方法中,new FileWriter(FILENAME)的默认行为是创建一个新文件(如果不存在),或者截断现有文件(如果存在),使其内容为空,然后才开始写入。因此,每次调用此方法时,文件中的旧数据都会被清除。
要解决FileWriter覆盖文件内容的问题,需要使用其支持追加模式的构造函数。通过将第二个参数设置为true,可以指示FileWriter在文件末尾追加新内容,而不是覆盖现有内容。
import java.io.FileWriter;
import java.io.IOException;
// ... 其他导入保持不变
public class NoteApp {
// ... 其他成员变量和方法保持不变
// 正确的写入方法:使用追加模式
public void fileHandlingCorrect() {
try {
// 使用FileWriter的追加模式构造函数
FileWriter fWriter = new FileWriter(FILENAME, true);
// 写入memory中新增的最后一条记录,避免重复写入
// 更优化的做法是只写入新增的内容,或者在每次写入前清空文件再写入整个memory
// 但为了演示追加,这里假设只追加最新一条
if (!memory.isEmpty()) {
fWriter.write(memory.get(memory.size() - 1) + '\n');
}
fWriter.close();
} catch (IOException e) {
System.err.println("写入文件时发生错误: " + e.getMessage());
}
}
// ... createNote() 方法中调用 fileHandlingCorrect()
}在new FileWriter(FILENAME, true)中,true参数告诉FileWriter以追加模式打开文件。这样,每次调用fileHandlingCorrect()时,新的笔记都会被添加到notes.data文件的末尾,而不会删除之前的记录。
注意事项:
立即学习“Java免费学习笔记(深入)”;
仅仅将数据追加到文件并不能完全实现“持久化”。一个完整的持久化方案还包括在程序启动时从文件中读取所有现有数据,并将其加载到内存(例如ArrayList)中,以便程序能够基于历史数据继续运行。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
// ... 其他导入保持不变
public class NoteApp {
private ArrayList<String> memory = new ArrayList<>();
private static final String FILENAME = "notes.data";
public NoteApp() {
loadNotesFromFile(); // 在构造函数中加载现有笔记
}
// 从文件加载现有笔记到内存
private void loadNotesFromFile() {
try (BufferedReader reader = new BufferedReader(new FileReader(FILENAME))) {
String line;
while ((line = reader.readLine()) != null) {
memory.add(line);
}
System.out.println("已从文件加载 " + memory.size() + " 条笔记。");
} catch (IOException e) {
// 文件不存在或读取错误是常见的,首次运行文件可能不存在
System.err.println("加载笔记时发生错误或文件不存在: " + e.getMessage());
}
}
// 正确的写入方法:使用追加模式
public void fileHandlingCorrect() {
try (FileWriter fWriter = new FileWriter(FILENAME, true)) { // 使用try-with-resources自动关闭
// 每次只写入新增的最后一条记录
if (!memory.isEmpty()) {
fWriter.write(memory.get(memory.size() - 1) + '\n');
}
} catch (IOException e) {
System.err.println("写入文件时发生错误: " + e.getMessage());
}
}
public void createNote() {
// ... (与之前相同)
Scanner insertNote = new Scanner(System.in);
LocalDate todayDate = LocalDate.now();
LocalTime nowTime = LocalTime.now();
String timeFormat = nowTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM));
String dateTime = todayDate.toString() + " at " + timeFormat;
System.out.println("\nEnter a note");
System.out.print("> ");
String note = insertNote.nextLine();
if (note == null || note.trim().isEmpty()) {
System.out.println("无效输入!请重试");
} else {
memory.add(note + " /" + dateTime);
fileHandlingCorrect(); // 调用追加写入方法
System.out.println("笔记已保存!\n");
}
}
public void displayNotes() {
System.out.println("\n--- 所有笔记 ---");
if (memory.isEmpty()) {
System.out.println("目前没有笔记。");
} else {
for (int i = 0; i < memory.size(); i++) {
System.out.println((i + 1) + ". " + memory.get(i));
}
}
System.out.println("----------------\n");
}
public static void main(String[] args) {
NoteApp app = new NoteApp();
app.displayNotes(); // 显示加载的笔记
app.createNote(); // 添加新笔记
app.displayNotes(); // 再次显示,包含新笔记
}
}在上述代码中:
为了提供一个更完整的、用户友好的应用程序,可以进一步整合这些功能,并遵循一些最佳实践:
通过结合追加写入和启动时加载数据,应用程序现在能够实现真正的数据持久化:用户添加的笔记在程序重启后依然存在,并且可以继续添加新的笔记。
本文详细阐述了Java FileWriter默认覆盖文件内容的机制,并提供了使用追加模式 (new FileWriter(FILENAME, true)) 解决此问题的方案。更重要的是,为了实现完整的数据持久化,我们还介绍了如何在程序启动时通过FileReader和BufferedReader从文件中加载现有数据到内存。结合try-with-resources进行资源管理,这些方法共同构成了一个健壮的、能够保存和恢复用户数据的Java文件操作实践。掌握这些技术对于开发需要长期存储用户数据的应用程序至关重要。
以上就是Java文件操作:如何避免FileWriter覆盖文件内容并实现数据持久化的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号