讲师中心 微信公众号
AI工具推荐 视频效率加速

c++怎么限制日志文件的最大大小_tellp检测与重新创建【详解】

老宇吖_3483

老宇吖_3483

发布时间:2026-03-25 15:44:49

|

181人浏览过

|

来源于php中文网

原创

用tellp()检测日志大小最轻量,但需先flush并处理-1返回值;超限时应原子重命名归档再以out|trunc|binary模式重建文件,避免追加或文本模式误判。

c++怎么限制日志文件的最大大小_tellp检测与重新创建【详解】

用 std::ofstream::tellp() 检测日志文件是否超限

直接读取当前写入位置是判断文件大小最轻量的方式,tellp() 返回的是流内部缓冲区 + 已刷盘字节数的近似值,不是系统级 stat() 结果,但对日志场景足够可靠。它快、无系统调用、不依赖平台 API。

常见错误是调用 tellp() 前没确保缓冲区已刷新,导致返回值偏小——比如连续写入后立刻检查,可能漏掉缓冲区里还没落盘的几百字节。

  • 每次写日志前先调用 log_stream.flush(),再调用 log_stream.tellp()
  • 如果日志量大、频率高,避免每条都 flush —— 改为「写前检测 + 写后按需 flush」:只在接近上限时 flush 并重检
  • 注意 tellp() 在文件为空或刚打开时可能返回 -1(失败),需判空:if (pos == -1) pos = 0;

超过大小后如何安全重建日志文件

直接 close() + open() 有竞态风险:多线程/多进程下可能丢日志,或新文件被覆盖。核心原则是「原子替换」+「旧文件保留命名」。

典型做法不是清空原文件,而是重命名旧文件、新建同名文件。Windows 和 Linux 下 rename() 对同目录文件是原子的,C++ 标准库没直接封装,得用 std::filesystem::rename()(C++17)或系统 API。

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

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载
  • 先获取当前文件名,如 "app.log",生成归档名 "app.log.20240520_142315"(含时间戳)
  • 用 std::filesystem::rename("app.log", archive_name) 原子重命名
  • 重新构造 std::ofstream 打开 "app.log"(自动创建新空文件)
  • 若 rename() 失败(如磁盘满、权限不足),不要静默忽略——记录错误并继续写原文件,否则日志丢失不可逆

std::ofstream 重建时的打开模式陷阱

很多人用 std::ofstream("app.log", std::ios::out) 重建,结果旧内容没清空、新日志追加到末尾——这完全违背“限制大小”的初衷。

关键在模式组合:std::ios::out | std::ios::trunc 才能清空重写;但仅 trunc 不够,必须显式指定 out,否则某些标准库实现会静默失败。

  • 正确写法:std::ofstream log_stream("app.log", std::ios::out | std::ios::trunc);
  • 别用 std::ios::app,它强制追加,trunc 会被忽略
  • 如果需要保留部分旧日志(如最后 100 行),就不能 trunc,得手动读取原文件、截断、再写入新文件——这已超出 tellp() 能力范围,需额外逻辑

跨平台与性能要注意的真实细节

tellp() 在 Windows 上对文本模式文件可能返回非字节数(换行符 \r\n 被算作 1 字符),导致大小误判。必须用二进制模式打开日志流,哪怕内容是纯文本。

另外,频繁调用 tellp() 本身开销极小,但配合 flush() 就变成实际 I/O,高并发写日志时可能成瓶颈。

  • 打开文件时务必加 std::ios::binary: std::ofstream("app.log", std::ios::out | std::ios::trunc | std::ios::binary)
  • 不要每条日志都检测大小——设一个阈值(如上限的 90%),只在写入后 tellp() 超过该值时才触发归档流程
  • 归档操作(rename + reopen)应尽量快,避免阻塞日志线程;如有大量日志待写,可先缓存到内存队列,归档完成后再批量刷出
事情说清了就结束。真正难的不是检测大小,而是归档瞬间的原子性、错误恢复和多线程下的状态同步——这些没法靠 tellp() 解决。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

3638

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

1029

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

363

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

519

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

369

2026.02.06

C++多线程并发控制与线程安全设计实践
C++多线程并发控制与线程安全设计实践

本专题围绕 C++ 在高性能系统开发中的并发控制技术展开,系统讲解多线程编程模型与线程安全设计方法。内容包括互斥锁、读写锁、条件变量、原子操作以及线程池实现机制,同时结合实际案例分析并发竞争、死锁避免与性能优化策略。通过实践讲解,帮助开发者掌握构建稳定高效并发系统的关键技术。

193

2026.03.16

Java 多线程与并发编程实战
Java 多线程与并发编程实战

深入讲解 Java 并发编程体系,涵盖 Thread / Runnable / Callable 线程创建方式、线程生命周期与状态转换、synchronized 同步锁与 Lock/ReentrantLock 显式锁、volatile 可见性保证、ThreadPool 线程池配置与调优(核心参数/拒绝策略)、JUC 并发工具类(CountDownLatch/CyclicBarrier/Semaphore/ConcurrentHashMa

309

2026.04.17

C++ 多线程使用教程大全
C++ 多线程使用教程大全

系统讲解 C++11 及后续标准引入的多线程编程能力,涵盖 std::thread 线程创建与生命周期管理、std::mutex / shared_mutex 互斥锁与读写锁、std::condition_variable 条件变量同步、std::atomic 原子操作与内存序(memory_order)、std::future / promise / async 异步任务、线程池的设计与实现、死锁检测与避免策略,帮助开发者编写正确高效

176

2026.04.28

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

0

2026.09.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn