-
Notifications
You must be signed in to change notification settings - Fork 1
Utils_FdWrapper
SweerItTer edited this page Feb 1, 2026
·
3 revisions
FdWrapper 是 utilsCore Utils 模块的核心类,提供文件描述符封装功能,自动管理文件描述符生命周期。
- 自动管理文件描述符生命周期
- 防止文件描述符泄漏
- 支持 RAII 模式
- 支持移动语义
- 打开文件
- 创建 socket
- 管道通信
- 事件监听
- 依赖: Linux 系统调用(fcntl.h, unistd.h)
- 被依赖: UdevMonitor, V4L2 等模块
FdWrapper 是文件描述符的封装类,提供:
- 自动关闭文件描述符
- 文件描述符访问
- 支持移动语义
- 防止拷贝
- RAII: 自动管理文件描述符生命周期
- Wrapper 模式: 封装文件描述符操作
explicit FdWrapper(int fd = -1);
~FdWrapper();参数说明:
-
fd(输入): 文件描述符,默认 -1 表示无效
返回值: 无
所有权归属:
- FdWrapper 拥有文件描述符的所有权
注意事项:
- 默认构造创建无效文件描述符(fd = -1)
- 析构时自动关闭有效的文件描述符
- 析构时打印关闭信息到 stdout
使用例程:
// 创建空包装器
FdWrapper fd1;
// 包装现有文件描述符
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
FdWrapper fd2(sockfd);FdWrapper(const FdWrapper&) = delete;
FdWrapper& operator=(const FdWrapper&) = delete;说明: 禁止拷贝构造和拷贝赋值,防止重复关闭文件描述符
FdWrapper(FdWrapper&& other) noexcept;参数说明:
-
other(输入): 右值引用
返回值: 无
所有权归属:
- 所有权从 other 转移给 this
注意事项:
- 接管 other 的文件描述符
- other 的 fd_ 设置为 -1,避免重复关闭
使用例程:
FdWrapper fd1(open("file.txt", O_RDONLY));
FdWrapper fd2 = std::move(fd1); // fd1 的 fd 转移给 fd2
// fd1 现在的 fd_ = -1FdWrapper& operator=(FdWrapper&& other) noexcept;参数说明:
-
other(输入): 右值引用
返回值: *this
所有权归属:
- 关闭当前文件描述符(如果有效)
- 接管 other 的文件描述符
注意事项:
- 先关闭当前文件描述符(如果有效)
- 接管 other 的文件描述符
- other 的 fd_ 设置为 -1
使用例程:
FdWrapper fd1(open("file1.txt", O_RDONLY));
FdWrapper fd2(open("file2.txt", O_RDONLY));
fd1 = std::move(fd2); // 关闭 file1,接管 file2int get() const;参数说明: 无
返回值: 文件描述符
所有权归属:
- 只读访问,不转移所有权
注意事项:
- 返回底层的文件描述符
- -1 表示无效文件描述符
使用例程:
FdWrapper fd(open("file.txt", O_RDONLY));
if (fd.get() >= 0) {
// 使用文件描述符
read(fd.get(), buffer, size);
}void closeFd();行为:
- 如果 fd_ >= 0,打印关闭信息到 stdout
- 调用 close(fd_)
- 设置 fd_ = -1
#ifndef FD_WRAPPER_H
#define FD_WRAPPER_H
#include <fcntl.h>
#include <unistd.h>
class FdWrapper {
public:
explicit FdWrapper(int fd = -1) : fd_(fd) {}
FdWrapper(const FdWrapper&) = delete;
FdWrapper& operator=(const FdWrapper&) = delete;
FdWrapper(FdWrapper&& other) noexcept : fd_(other.fd_) {
other.fd_ = -1;
}
FdWrapper& operator=(FdWrapper&& other) noexcept {
if (this != &other) {
closeFd();
fd_ = other.fd_;
other.fd_ = -1;
}
return *this;
}
~FdWrapper() {
closeFd();
}
int get() const { return fd_; }
private:
int fd_;
void closeFd() {
if (fd_ >= 0) {
fprintf(stdout, "[FdWrapper] close fd: %d\n", fd_);
close(fd_);
fd_ = -1;
}
}
};
#endif // FD_WRAPPER_H- 无锁设计
- 不保证线程安全
- 单线程使用
- 多线程使用需要外部同步
FdWrapper fd(open("file.txt", O_RDONLY));
if (fd.get() >= 0) {
char buffer[1024];
ssize_t n = read(fd.get(), buffer, sizeof(buffer));
printf("Read %zd bytes\n", n);
}
// 文件描述符自动关闭
// 输出: [FdWrapper] close fd: 3FdWrapper sockfd(socket(AF_INET, SOCK_STREAM, 0));
if (sockfd.get() >= 0) {
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
if (connect(sockfd.get(), (struct sockaddr*)&addr, sizeof(addr)) == 0) {
printf("Connected\n");
}
}
// Socket 自动关闭
// 输出: [FdWrapper] close fd: 4FdWrapper create_fd() {
FdWrapper fd(open("file.txt", O_RDONLY));
return fd; // 移动构造
}
auto fd = create_fd();
// 使用 fd...
// 析构时自动关闭FdWrapper fd1(open("file1.txt", O_RDONLY));
FdWrapper fd2(open("file2.txt", O_RDONLY));
printf("Before: fd1=%d, fd2=%d\n", fd1.get(), fd2.get());
fd1 = std::move(fd2);
printf("After: fd1=%d, fd2=%d\n", fd1.get(), fd2.get());
// 输出: [FdWrapper] close fd: 3void process_file(const std::string& filename) {
FdWrapper fd(open(filename.c_str(), O_RDONLY));
if (fd.get() < 0) {
throw std::runtime_error("Failed to open file");
}
// 处理文件...
// 即使抛出异常,文件描述符也会自动关闭
}- 自动关闭: 析构时自动关闭文件描述符
- 所有权: 注意所有权转移,使用移动语义
- 禁止拷贝: 只支持移动,不支持拷贝
- 无效描述符: -1 表示无效文件描述符
- 调试信息: 析构时会打印关闭信息
- 线程安全: 不保证线程安全
- 异常安全: RAII 保证异常安全
- 移动后: 移动后的对象 fd_ = -1
- UdevMonitor - Udev 监控
- CameraController - 相机控制器
- Utils 模块总览
主页
API 文档
DMA 模块
DRM 模块
- DRM 模块总览
- DeviceController - DRM 设备控制器
- DrmLayer - DRM 图层管理
- PlanesCompositor - DRM 平面合成器
- DrmBpp - DRM 格式定义
NET 模块
- NET 模块总览
- TcpServer - TCP 服务器
- SocketConnection - Socket 连接管理
- CommandHandler - 命令处理器
- DataPacket - 数据包
V4L2 模块
- V4L2 模块总览
- CameraController - V4L2 摄像头控制器
- Frame - V4L2 帧数据结构
- FormatTool - V4L2 格式工具
- Exception - V4L2 异常类
V4L2Param 模块
- V4L2Param 模块总览
- ParamControl - 参数控制
- ParamLogger - 参数日志
- ParamProcessor - 参数处理器
RGA 模块
- RGA 模块总览
- RgaConverter - RGA 转换器
- RgaProcessor - RGA 处理器
- FormatTool - RGA 格式工具
MPP 模块
- MPP 模块总览
- EncoderContext - 编码器上下文
- EncoderCore - 编码器核心
- JpegEncoder - JPEG 编码器
- StreamWriter - 流写入器
- MppResourceGuard - MPP 资源守护
- FileTools - 文件工具
- FormatTool - 格式工具
Sys 模块
- Sys 模块总览
- CpuMonitor - CPU 监控器
- MemoryMonitor - 内存监控器
- Base - 基础类
Mouse 模块
- Mouse 模块总览
- Watcher - 鼠标监视器
Utils 模块
- Utils 模块总览
- AsyncThreadPool - 异步线程池
- ConcurrentQueue - 并发队列
- FdWrapper - 文件描述符包装器
- FenceWatcher - 围栏监视器
- FixedSizePool - 固定大小对象池
- Logger - 日志记录器
- ObjectsPool - 对象池
- OrderedQueue - 有序队列
- ProgressBar - 进度条
- SafeQueue - 安全队列
- SharedBufferState - 共享缓冲区状态
- SimpleVariant - 简单变体类型
- ThreadPauser - 线程暂停器
- ThreadUtils - 线程工具
- Types - 类型定义
- UdevMonitor - Udev 监视器