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

Java中如何设置.csv文件的最大大小,超限时自动删除旧数据追加新内容

解决方案

你需要实现的是滚动式CSV写入逻辑,完全可以做到不缓存全文件内容,内存占用极低,以下是具体实现思路和可直接运行的代码:

核心逻辑

同时兼容行限制和大小限制两个触发条件,触发后自动删除最旧的第一条数据:

  • 写入前先判断CSV文件是否存在,不存在则先写入表头
  • 每次写入新数据前,分别统计当前文件的行数和文件大小,两个条件任意一个触达上限就启动滚动逻辑
  • 滚动逻辑不需要把全文件读进内存,通过临时文件逐行读写:先写表头,跳过最旧的第一条数据,复制剩余所有旧数据,最后追加新数据,再用临时文件覆盖原文件即可

优化后可运行代码

import java.io.*;
import java.time.LocalDate;
import java.time.LocalTime;

public class RollingCsvWriter {
    // 可自定义配置参数
    private static final int MAX_DATA_ROWS = 1000; // 最大数据行数(不含表头)
    private static final long MAX_FILE_SIZE = 2 * 1024 * 1024; // 最大文件大小2MB
    private static final String FILE_PATH = "myCSV.csv";
    private static final String CSV_HEADER = "Date; Time\n";

    public static void main(String[] args) {
        File csvFile = new File(FILE_PATH);
        // 首次创建文件时写入表头,避免重复写表头
        if (!csvFile.exists()) {
            try (FileWriter writer = new FileWriter(csvFile)) {
                writer.append(CSV_HEADER);
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
        }

        while (true) {
            try {
                writeNewRecord(csvFile, LocalDate.now() + ";" + LocalTime.now() + "\n");
                Thread.sleep(60000);
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static void writeNewRecord(File csvFile, String newLine) throws IOException {
        long currentFileSize = csvFile.length();
        int currentTotalRows = countTotalRows(csvFile);

        // 未达限制直接追加写入
        if (currentTotalRows < MAX_DATA_ROWS + 1 && currentFileSize + newLine.getBytes().length < MAX_FILE_SIZE) {
            try (FileWriter writer = new FileWriter(csvFile, true)) {
                writer.append(newLine);
            }
            return;
        }

        // 达到限制,滚动删除最旧的一条数据
        File tempFile = new File("temp_" + FILE_PATH);
        try (BufferedReader reader = new BufferedReader(new FileReader(csvFile));
             FileWriter tempWriter = new FileWriter(tempFile)) {
            // 写入表头
            tempWriter.append(reader.readLine()).append("\n");
            // 跳过最旧的第一条数据
            reader.readLine();
            // 复制剩余所有旧数据
            String line;
            while ((line = reader.readLine()) != null) {
                tempWriter.append(line).append("\n");
            }
            // 追加新数据
            tempWriter.append(newLine);
        }
        // 临时文件写入完成后覆盖原文件,避免写入中断损坏原文件
        if (csvFile.delete()) {
            tempFile.renameTo(csvFile);
        }
    }

    // 统计文件总行数,只计数不存储内容,内存占用极低
    private static int countTotalRows(File csvFile) throws IOException {
        int rows = 0;
        try (BufferedReader reader = new BufferedReader(new FileReader(csvFile))) {
            while (reader.readLine() != null) {
                rows++;
            }
        }
        return rows;
    }
}

方案优势

  • 内存占用极低:全程逐行读写,不需要加载全文件内容,最多只存储单行字符串,就算文件到2MB上限也不会占用过多内存
  • 可靠性高:所有修改先写临时文件,完成后才覆盖原文件,就算写入过程中断也不会损坏原文件
  • 兼容性强:同时支持行数和文件大小两个限制条件,可根据需求调整参数优先级

如果想要进一步优化性能,可以在程序中缓存当前行数,不需要每次写入前都遍历统计,对你每分钟写入一次的场景来说,优化前后感知差异极小。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:27:03