Java 文件操作:解决 FileWriter 覆盖问题并实现数据追加

Java 文件操作:解决 FileWriter 覆盖问题并实现数据追加

本文旨在解决Java中FileWriter默认覆盖文件内容导致数据丢失的问题。我们将深入探讨FileWriter的工作机制,并介绍如何通过使用其构造函数中的append参数来启用追加模式,从而确保每次写入操作都能在文件末尾添加新数据,有效保存历史记录。文章还将涵盖文件读取以恢复数据到内存,以及文件I/O的最佳实践。

理解 FileWriter 的默认行为

在java中,java.io.filewriter 是一个方便的字符流写入器,用于将字符数据写入文件。然而,它的一个常见陷阱是其默认行为:当使用 new filewriter(“filename”) 构造函数时,如果指定的文件已存在,它会清空该文件,然后从头开始写入新内容。这意味着每次程序运行并调用此构造函数时,之前保存的所有数据都将被擦除。

考虑以下代码片段,它展示了这种默认行为可能导致数据丢失的情况:

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 memory = new ArrayList();    private static final String FILENAME = "notes.data";    // 原始的 fileHandling 方法,存在覆盖问题    public void fileHandlingProblematic() {        try {            // 每次创建 FileWriter 都会清空文件            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("Invalid input! Try again");        } else {            memory.add(note + " /" + dateTime);            fileHandlingProblematic(); // 调用有问题的方法            System.out.println("Note is saved!n");        }    }    // 主方法用于测试    public static void main(String[] args) {        NoteApp app = new NoteApp();        // 第一次运行,输入笔记        app.createNote();         // 再次运行程序,输入新笔记,旧笔记会被覆盖    }}

上述代码中,每次调用 fileHandlingProblematic() 方法时,new FileWriter(FILENAME) 都会重新创建一个文件写入流。如果 notes.data 文件已经存在,它会被截断(清空),然后 memory 中当前的内容才会被写入。因此,当程序重新启动时,memory 列表是空的,文件内容也会被清空,导致数据丢失。

解决方案:启用追加模式

要解决 FileWriter 覆盖文件内容的问题,我们需要使用 FileWriter 的另一个构造函数:FileWriter(String fileName, boolean append)。当 append 参数设置为 true 时,FileWriter 将以追加模式打开文件。这意味着如果文件已存在,新数据将被写入到文件末尾,而不会清空原有内容。

以下是修正后的 fileHandling 方法:

立即学习“Java免费学习笔记(深入)”;

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;import java.io.BufferedReader;import java.io.FileReader;import java.io.BufferedWriter;public class NoteAppCorrected {    private ArrayList memory = new ArrayList();    private static final String FILENAME = "notes.data";    public NoteAppCorrected() {        loadNotesFromFile(); // 程序启动时加载现有笔记    }    // 修正后的 fileHandling 方法,使用追加模式    public void fileHandling() {        try (BufferedWriter bWriter = new BufferedWriter(new FileWriter(FILENAME, true))) { // 启用追加模式            // 只写入新添加的笔记,或者在每次保存时写入整个列表(取决于需求)            // 如果每次都写入整个列表,则不需要append模式,但需要先清空文件            // 为了避免重复写入,这里我们假设每次只追加新内容,或者在程序退出时统一写入            // 更常见的做法是在每次修改后,将整个memory列表重新写入文件(但不使用append模式)            // 或者只在程序退出时将所有内容写入文件            // 为了匹配原问题的“保存所有输入”并“不覆盖”,这里假设每次只写入最新的内容            // 更好的做法是,在每次修改后,将整个memory列表重新写入文件,但不是追加模式            // 考虑原问题意图,每次写入都是整个列表,那么append模式应该这样使用:            // 每次fileHandling只写入当前memory的全部内容,但前提是memory已经包含了之前的内容            // 否则,如果memory每次都是从零开始,那么即使是append模式也会导致重复数据。            // 最合理的方案是:程序启动时加载所有数据,修改memory,程序退出时将memory全部写入文件(不使用append)            // 为了演示append模式,这里将每次新添加的元素追加到文件            // 如果是每次保存整个列表,则不应使用append模式,而是每次都覆盖            // 如果要保存所有输入,且每次启动都保留,那么逻辑应该是:            // 1. 启动时读取文件内容到memory            // 2. 用户输入,添加到memory            // 3. 将整个memory写入文件 (不使用append,因为memory已包含所有历史数据)            // 这种情况下,FileWriter(FILENAME) 即可,因为memory已是最新状态            // 鉴于原问题意图是“保存每次输入”,且“不覆盖”,            // 最直接的修改是让FileWriter在每次写入时追加,但这意味着每次写入都会重复之前的内容。            // 正确的逻辑是:程序启动时加载所有数据,然后每次将完整的内存状态写入文件。            // 修正:这里不应每次都写入整个memory,而是每次只追加新内容,或者在程序结束时统一写入            // 为了保持与原问题“每次写入memory所有内容”的逻辑一致,            // 且解决“覆盖”问题,这意味着每次文件操作都应包含之前的内容。            // 因此,正确的逻辑是:            // 1. 程序启动时,从文件加载所有历史数据到 `memory`。            // 2. 用户添加新数据,将其加入 `memory`。            // 3. 调用 `fileHandling()` 时,将 `memory` 的所有内容写入文件,但不使用追加模式,            //    因为 `memory` 已经包含了所有历史数据,覆盖旧文件是正确的。            //    如果坚持使用 `append` 模式,则 `fileHandling` 每次只应写入最新添加的那条数据。            // 为了遵循原问题“将arraylist元素发送到文件”,并且解决“覆盖”问题,            // 最直接的修改是:每次将ArrayList的全部内容写入文件,但首先要确保ArrayList包含了历史数据。            // 这意味着在程序启动时,必须先将文件中的数据读取到ArrayList。            // 那么,`FileWriter` 就不应该使用 `append` 模式,而是每次都覆盖,因为 `memory` 已经是最新、最完整的状态。            // 如果坚持在 `fileHandling` 中使用 `append` 模式来避免覆盖,            // 那么 `fileHandling` 应该只写入最新添加的那个元素。            // 但原代码 `for (int x = 0; x  ");        String note = insertNote.nextLine();        if (note == null || note.trim().isEmpty()) {            System.out.println("Invalid input! Try again");        } else {            memory.add(note + " /" + dateTime);            fileHandling(); // 调用修正后的方法            System.out.println("Note is saved!n");        }    }    // 主方法用于测试    public static void main(String[] args) {        NoteAppCorrected app = new NoteAppCorrected();        app.createNote();        // 再次运行程序,输入新笔记,旧笔记应被保留(但可能重复)        // 打印当前内存中的笔记        System.out.println("当前内存中的笔记:");        app.memory.forEach(System.out::println);    }}

在上述修正后的 fileHandling 方法中,new FileWriter(FILENAME, true) 确保了每次写入操作都是在文件末尾追加内容。同时,为了满足“程序再次运行,内容回到数组”的需求,我们在 NoteAppCorrected 的构造函数中添加了 loadNotesFromFile() 方法,它会在程序启动时从文件中读取所有历史数据并加载到 memory 列表中。

注意事项与更优的文件 I/O 实践

尽管 FileWriter(FILENAME, true) 解决了文件覆盖的问题,但上述 fileHandling 方法(每次都循环 memory 列表并使用 append=true)会导致一个新问题:文件中的数据会重复。每次调用 fileHandling() 时,memory 中包含的所有历史和最新笔记都会被再次追加到文件末尾。

为了实现“保存所有输入,并在下次启动时恢复”的健壮逻辑,推荐以下最佳实践:

程序启动时加载所有数据:使用 FileReader 和 BufferedReader 在程序启动时一次性将文件中的所有数据读取到内存

以上就是Java 文件操作:解决 FileWriter 覆盖问题并实现数据追加的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/38615.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
打造实时推送:如何使用pusher/pusher-push-notifications构建高效的PHP推送服务
上一篇 2026年11月6日 19:12:53
Golang如何优化CPU占用率_Golang CPU占用优化实践
下一篇 2025年12月16日 21:27:59

相关推荐

  • 全民 AI 游戏时代到来!耕升助 SDR 游戏 HDR 化

    全民 AI 游戏时代到来!耕升助 SDR 游戏 HDR 化全民 AI 游戏时代到来!耕升助 SDR 游戏 HDR 化全民 AI 游戏时代到来!耕升助 SDR 游戏 HDR 化全民 AI 游戏时代到来!耕升助 SDR 游戏 HDR 化

    在游戏领域,高动态范围(hdr)技术一直被视为提升视觉体验的重要因素之一。它能提供宽广的色彩范围和高的对比度,使画面更生动真实,增加层次感。同时,可以改善光影效果,使光源和阴影更真实,增强沉浸感和真实感,提升视觉舒适度和可视性。此外,还能减少画面眩光和影子失真,使玩家更易辨认物体和场景,提高游戏的可…

    2026年11月6日 • 用户投稿
    300
  • SignGemma— 谷歌DeepMind推出的手语翻译AI模型

    SignGemma— 谷歌DeepMind推出的手语翻译AI模型SignGemma— 谷歌DeepMind推出的手语翻译AI模型SignGemma— 谷歌DeepMind推出的手语翻译AI模型SignGemma— 谷歌DeepMind推出的手语翻译AI模型

    SignGemma是什么 signgemma 是由谷歌 deepmind 研发团队推出的一款全球领先的手语翻译ai系统。该模型致力于将美国手语(asl)转换为英语文本,运用多模态训练方式,融合视觉与文本数据,精确辨识手语动作并即时生成口语文本。signgemma 拥有极高的准确性及上下文理解力,响应…

    2026年11月6日 • 用户投稿
    100
  • Gradle多模块项目依赖配置指南:解决子项目依赖问题

    Gradle多模块项目依赖配置指南:解决子项目依赖问题Gradle多模块项目依赖配置指南:解决子项目依赖问题Gradle多模块项目依赖配置指南:解决子项目依赖问题Gradle多模块项目依赖配置指南:解决子项目依赖问题

    本文旨在帮助开发者解决Gradle多模块项目中子项目依赖无法正确识别的问题。通过清晰的步骤和示例代码,详细讲解如何配置settings.gradle文件,以及如何在子项目的build.gradle文件中声明项目依赖,确保Gradle能够正确构建和管理多模块项目。通过遵循本文的指导,开发者可以避免常见…

    2026年11月6日 • 用户投稿
    100
  • 使用 Spring JdbcTemplate 访问 DynamoDB 的替代方案

    使用 Spring JdbcTemplate 访问 DynamoDB 的替代方案使用 Spring JdbcTemplate 访问 DynamoDB 的替代方案使用 Spring JdbcTemplate 访问 DynamoDB 的替代方案使用 Spring JdbcTemplate 访问 DynamoDB 的替代方案

    本文旨在帮助开发者寻找使用 Spring JdbcTemplate 访问 DynamoDB 的替代方案。由于 DynamoDB 基于 HTTP 协议,连接是短连接,与 JDBC 的长连接特性不同,因此无法直接使用 JdbcTemplate。本文将探讨可行的替代方案,并通过代码示例和注意事项,指导开发…

    2026年11月6日 • 用户投稿
    000
  • 百度输入法如何设置固定第一候选为英文_百度输入法候选优先语言设置教程

    百度输入法如何设置固定第一候选为英文_百度输入法候选优先语言设置教程百度输入法如何设置固定第一候选为英文_百度输入法候选优先语言设置教程百度输入法如何设置固定第一候选为英文_百度输入法候选优先语言设置教程百度输入法如何设置固定第一候选为英文_百度输入法候选优先语言设置教程

    可通过设置让百度输入法在中文模式下第一候选词为英文。首先在“输入设置”中开启“英文优先显示”或“智能中英混输”功能,使拼音输入时自动推荐对应英文;其次可启用“英文联想优化”提升准确率;最后通过“自定义短语”功能,将特定拼音绑定固定英文单词,确保其始终优先显示,从而实现高效中英混输。 如果您在使用百度…

    2026年11月6日 • 用户投稿
    100
  • 如何使用Spring JdbcTemplate类操作DynamoDB?

    如何使用Spring JdbcTemplate类操作DynamoDB?如何使用Spring JdbcTemplate类操作DynamoDB?如何使用Spring JdbcTemplate类操作DynamoDB?如何使用Spring JdbcTemplate类操作DynamoDB?

    本文旨在探讨在Spring环境下,如何借助类似JdbcTemplate的机制来操作DynamoDB数据库。由于DynamoDB的HTTP连接特性与传统JDBC连接的持久性不同,直接使用JdbcTemplate并不适用。本文将介绍如何利用AWS SDK for Java和Spring框架,实现高效的D…

    2026年11月6日 • 用户投稿
    200
  • OpenSearch 宣布成立 Observability TAG

    OpenSearch 宣布成立 Observability TAGOpenSearch 宣布成立 Observability TAGOpenSearch 宣布成立 Observability TAGOpenSearch 宣布成立 Observability TAG

    OpenSearch 项目近日宣布正式成立观测性技术咨询组(Observability TAG),该小组隶属于项目的技术指导委员会,旨在为 OpenSearch 生态系统中的观测能力提供战略方向与技术建议。 据悉,Observability TAG 的核心使命是定义、推广并倡导最佳实践,助力用户更高…

    2026年11月6日 • 用户投稿
    000
  • 淘宝消息通知延迟怎么办 淘宝消息提醒优化与修复方法

    淘宝消息通知延迟怎么办 淘宝消息提醒优化与修复方法淘宝消息通知延迟怎么办 淘宝消息提醒优化与修复方法淘宝消息通知延迟怎么办 淘宝消息提醒优化与修复方法淘宝消息通知延迟怎么办 淘宝消息提醒优化与修复方法

    消息通知延迟影响客服体验,需检查千牛设置中提醒功能是否开启,确认系统通知权限已授权,优化网络与后台运行状态,并更新千牛至最新版本以修复推送问题。 如果您在使用淘宝或千牛时,发现消息通知出现延迟,导致无法及时响应买家咨询,这可能会影响店铺的客服体验分和订单转化。以下是针对此问题的多种排查与修复方法: …

    2026年11月6日 • 用户投稿
    100
  • 使用tpetry/laravel-postgresql-enhanced扩展Laravel,解决PostgreSQL缺失功能问题

    最近在开发一个 Laravel 项目时,我需要用到 PostgreSQL 数据库的一些高级特性,例如物化视图、数组类型、全文索引等。然而,Laravel 默认的数据库驱动并不能完全支持这些功能,导致我需要编写大量的原生 SQL 语句,这不仅增加了开发难度,也降低了代码的可维护性。 为了解决这个问题,…

    2026年11月6日
    100
  • 即梦ai怎样制作倒放视频 即梦ai反向播放功能教程

    即梦ai怎样制作倒放视频 即梦ai反向播放功能教程即梦ai怎样制作倒放视频 即梦ai反向播放功能教程即梦ai怎样制作倒放视频 即梦ai反向播放功能教程即梦ai怎样制作倒放视频 即梦ai反向播放功能教程

    即梦ai制作倒放视频的具体步骤是:1. 打开即梦ai并导入视频文件;2. 在“时间线”功能中选中视频并点击“反向播放”按钮;3. 预览并导出倒放视频。制作倒放视频在即梦ai中非常简单,只需几步操作就能实现反向播放效果,这些步骤包含了帧的反序排列和音频的反向播放等技术处理。 ☞☞☞AI 智能聊天, 问…

    2026年11月6日 • 用户投稿
    200
  • 最新研究:AI 已经能在几分钟内通过 CFA 最难级别考试

    最新研究:AI 已经能在几分钟内通过 CFA 最难级别考试最新研究:AI 已经能在几分钟内通过 CFA 最难级别考试最新研究:AI 已经能在几分钟内通过 CFA 最难级别考试最新研究:AI 已经能在几分钟内通过 CFA 最难级别考试

    纽约大学斯特恩商学院联合金融科技企业goodfin发布的最新研究指出,当前顶尖的推理型人工智能模型,如gemini 2.5 pro与claude opus 4,仅需几分钟即可在未经额外训练的情况下顺利通过cfa三级考试。部分领先ai的表现准确率甚至显著超出该考试的合格标准。 相比之下,人类考生通常需…

    2026年11月6日 • 用户投稿
    100
  • 秒拍账号安全设置页面_秒拍安全中心官网入口

    秒拍账号安全设置页面_秒拍安全中心官网入口秒拍账号安全设置页面_秒拍安全中心官网入口秒拍账号安全设置页面_秒拍安全中心官网入口秒拍账号安全设置页面_秒拍安全中心官网入口

    秒拍账号安全设置在个人中心的“高级设置”中。登录后点击左上角功能菜单,选择“高级设置”,进入“安全中心”管理登录记录、绑定密保手机并定期更换高强度密码以提升安全性。 秒拍账号安全设置页面在哪里?这是不少网友都关注的,接下来由PHP小编为大家带来秒拍安全中心官网入口,感兴趣的网友一起随小编来瞧瞧吧! …

    2026年11月6日 • 用户投稿
    600
  • 即梦ai如何导出高清封面 即梦ai缩略图生成攻略

    即梦ai如何导出高清封面 即梦ai缩略图生成攻略即梦ai如何导出高清封面 即梦ai缩略图生成攻略即梦ai如何导出高清封面 即梦ai缩略图生成攻略即梦ai如何导出高清封面 即梦ai缩略图生成攻略

    在即梦ai中,导出高清封面和生成缩略图非常简单。1) 完成创作后,点击“导出”按钮,选择“高清封面”选项并下载,使用高分辨率素材和检查导出设置可确保质量。2) 调整画面的构图和色彩,选择对比度高的画面来生成吸引人的缩略图,简化画面和使用鲜艳色彩可提升效果。 ☞☞☞AI 智能聊天, 问答助手, AI …

    2026年11月6日 • 用户投稿
    100
  • 使用 Spring JdbcTemplate 类访问 DynamoDB 的方法

    使用 Spring JdbcTemplate 类访问 DynamoDB 的方法使用 Spring JdbcTemplate 类访问 DynamoDB 的方法使用 Spring JdbcTemplate 类访问 DynamoDB 的方法使用 Spring JdbcTemplate 类访问 DynamoDB 的方法

    本文旨在探讨如何利用 Spring 生态系统中的 JdbcTemplate 类的设计思想,应用于 NoSQL 数据库 DynamoDB 的数据访问。虽然 JdbcTemplate 并非直接为 DynamoDB 设计,但我们可以借鉴其设计思想,通过 Spring 提供的其他工具和库,实现类似的数据访问…

    2026年11月6日 • 用户投稿
    000
  • Kimi智能助手适合哪些人群使用 Kimi人工智能助手全方位功能体验报告

    kimi智能助手最适合对信息处理效率有高要求且渴望激发新灵感的人群,它能快速提炼海量文本的核心要点并提供多角度洞察;2. 在学习与研究中,kimi可高效概括文献、对比理论、构建认知网络,辅助用户降低信息过载焦虑并提供批判性视角;3. 内容创作者可利用kimi生成创意框架、撰写初稿、模拟多种写作风格,…

    2026年11月6日
    000
  • 苹果手机如何更换id账号

    准备工作 在准备更换Apple ID之前,请先确认你已记住当前使用的Apple ID密码,因为在退出账户时需要进行身份验证。同时,请提前准备好新的Apple ID账号和对应密码,确保信息准确无误。 更换步骤 进入手机的“设置”应用,点击顶部显示的Apple ID头像或名称,进入Apple ID管理界…

    2026年11月6日
    100
  • 华为 Vision 智慧屏 5 Pro 预售:全新超薄线上旗舰款鸿蒙 AI 电视让客厅温暖重聚

    华为 Vision 智慧屏 5 Pro 预售:全新超薄线上旗舰款鸿蒙 AI 电视让客厅温暖重聚华为 Vision 智慧屏 5 Pro 预售:全新超薄线上旗舰款鸿蒙 AI 电视让客厅温暖重聚华为 Vision 智慧屏 5 Pro 预售:全新超薄线上旗舰款鸿蒙 AI 电视让客厅温暖重聚华为 Vision 智慧屏 5 Pro 预售:全新超薄线上旗舰款鸿蒙 AI 电视让客厅温暖重聚

    父亲握着手机刷赛事集锦,母亲蜷在沙发上用平板追剧集,孩子趴在地毯上盯着绘本——客厅中央那台大电视,屏幕黑得像面冰冷的镜子。这场景或许是当下许多家庭的缩影:家人被各自的屏幕筑起各自的 ” 小世界 “,本该热闹的客厅少了家人间的闲话家常,少量几分亲近。 想要打破这份 &#8221…

    2026年11月6日 • 用户投稿
    000
  • 2025 旅行微单首选:佳能 R50V 获专业评测推荐 8000 元以内视频拍照全能机

    2025 旅行微单首选:佳能 R50V 获专业评测推荐  8000 元以内视频拍照全能机2025 旅行微单首选:佳能 R50V 获专业评测推荐  8000 元以内视频拍照全能机2025 旅行微单首选:佳能 R50V 获专业评测推荐  8000 元以内视频拍照全能机2025 旅行微单首选:佳能 R50V 获专业评测推荐  8000 元以内视频拍照全能机

    在智能手机影像能力不断提升的今天,越来越多旅行爱好者开始将微单相机作为出行创作的核心装备。随着十一国庆假期临近,微单产品迎来年度销售高峰,消费者在众多选择中如何决策?尤其在8000元以下的便携微单市场中,经过专业评测与用户口碑双重验证,佳能 r50v 凭借全面均衡的表现脱颖而出,成为旅行摄影领域的权…

    2026年11月6日 • 用户投稿
    100
  • DeepSeek怎么关联飞书 团队协作智能化改造方案

    DeepSeek怎么关联飞书 团队协作智能化改造方案DeepSeek怎么关联飞书 团队协作智能化改造方案DeepSeek怎么关联飞书 团队协作智能化改造方案DeepSeek怎么关联飞书 团队协作智能化改造方案

    deepseek与飞书可以通过api集成或第三方插件关联,提升团队协作智能化。1. api集成需注册开发者账号,获取api密钥,并在飞书平台编写自定义应用嵌入deepseek的api。2. deepseek可分析团队沟通模式,优化工作流程,智能分配任务。3. 集成挑战包括api稳定性和数据隐私,需调…

    2026年11月6日 • 用户投稿
    100
  • 谷歌浏览器最新官方站点 Chrome浏览器在线登录入口

    谷歌浏览器最新官方站点 Chrome浏览器在线登录入口谷歌浏览器最新官方站点 Chrome浏览器在线登录入口谷歌浏览器最新官方站点 Chrome浏览器在线登录入口谷歌浏览器最新官方站点 Chrome浏览器在线登录入口

    谷歌浏览器最新官方站点及Chrome浏览器在线登录入口是https://www.google.com/chrome/,用户可在此下载浏览器并登录账号以同步书签、密码、历史记录等数据,享受跨设备一致体验。 谷歌浏览器最新官方站点 Chrome浏览器在线登录入口在哪里?这是不少网友都关注的,接下来由PH…

    2026年11月6日 • 用户投稿
    100

发表回复

登录后才能评论
关注微信