C++实现文件操作类

总的来说,这是一个非常优秀、健壮且线程安全的文件操作类设计。 成功地应用了 C++ 的核心特性(如继承、多态、RAII、std::mutex等)来解决实际问题。

下面我将进行一个全面的回顾,并提出一些非常细微的建议,这些建议更多是关于代码风格和潜在的边缘情况处理。

代码亮点(总结)

设计模式:正确使用了 ** 接口类(FileBase)和实现类(TextFile)** 的设计模式,通过纯虚函数定义了清晰的契约。

线程安全:TextFile 类内部使用了 std::mutex 和 std::lock_guard 来保护所有对共享资源(file_stream_, is_open_)的访问,实现了线程安全。

资源管理:严格遵守RAII原则。

析构函数会自动调用 Close(),确保文件被关闭,资源被释放。

Open() 和 Close() 方法正确地管理了 file_stream_ 和 is_open_ 的状态。

错误处理:Write 和 WriteLine 方法通过检查 file_stream_.fail() 来判断操作是否成功,并返回 bool 值,让调用者可以处理失败情况。

封装性:

FileBase 中的 filename_ 为 protected,允许子类访问,同时防止外部直接修改。

TextFile 的成员变量 mutex_, file_stream_, is_open_ 均为 private,保证了类的内部状态不会被外部随意篡改。

虚析构函数:FileBase 正确地声明了 virtual ~FileBase() = default;,确保了通过基类指针删除子类对象时的行为是正确的。

cpp 复制代码
#include <string>
#include <ios>
class FileBase
{
public:
    FileBase() = default;
    virtual ~FileBase() = default;
    virtual bool Open(const std::string &fileName, std::ios_base::openmode mode) = 0;
    virtual void Close() = 0;
    virtual void Flush() = 0;
    virtual bool IsOpen() const = 0;
    virtual bool Write(const std::string & data) = 0;
    virtual bool WriteLine(const std::string & line) = 0;
    virtual std::string Read() = 0;
    virtual std::string ReadLine() = 0;
protected:
    std::string filename_;
};
cpp 复制代码
#include <fstream>
#include <mutex>
#include "file_base.hpp"
class TextFile :public FileBase
{
private:
    mutable std::mutex mutex_;
    std::fstream file_stream_;
    bool is_open_; 
public:
    TextFile();
    ~TextFile();
    bool Open(const std::string &fileName,
        std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) override;
    void Close() override;
    void Flush() override;
    bool IsOpen() const override;
    bool Write(const std::string & data) override;
    bool WriteLine(const std::string & line)override;
    std::string Read() override;
    std::string ReadLine() override;
};
cpp 复制代码
#include "file_text.hpp"
#include <sstream>

TextFile::TextFile():file_stream_(),is_open_(false)
{
}

TextFile::~TextFile()
{
    Close();
}

bool TextFile::Open(const std::string &fileName,std::ios_base::openmode mode) {
    std::lock_guard<std::mutex> lock(mutex_);
    //如果TextFile对象已经打开一个文件,再次调用open会失败,fstream对象不能同时打开多个文件
    //如果已打开其他文件,先关闭
    if(is_open_){
        file_stream_.close();
    }
    file_stream_.open(fileName, mode);
    is_open_ = file_stream_.is_open();
    if(is_open_){
        filename_ = fileName;
    }
    return is_open_;
}
void TextFile::Close(){
    std::lock_guard<std::mutex> lock(mutex_);
    if(is_open_){
        file_stream_.close();
        is_open_ = false;
    }
}

void TextFile::Flush(){
    std::lock_guard<std::mutex> lock(mutex_);
    if(is_open_)
        file_stream_.flush();//文件未打开,调用flush不会崩溃,但也是一个无意义的操作
}

bool TextFile::IsOpen() const{
    //这里要加锁,防止另一个线程正在写,这时候读会产生未定义行为
    std::lock_guard<std::mutex> lock(mutex_);
    return is_open_;
}

bool TextFile::Write(const std::string& data){
    std::lock_guard<std::mutex> lock(mutex_);
    if(!is_open_) return false;
    file_stream_ << data; //如果磁盘已满,写入会失败
    return !file_stream_.fail();
}

bool TextFile::WriteLine(const std::string & line){
    std::lock_guard<std::mutex> lock(mutex_);
    if(!is_open_) return false;
    file_stream_ << line << '\n';
    return !file_stream_.fail();
}

std::string TextFile::Read(){
    std::lock_guard<std::mutex> lock(mutex_);
    if(!is_open_) return "";
    std::ostringstream ss;
    ss << file_stream_.rdbuf();
    return ss.str();
}

std::string TextFile::ReadLine(){
    std::lock_guard<std::mutex> lock(mutex_);
    if(!is_open_) return "";
    std::string line;
    if(getline(file_stream_,line)){
        return line;
    }else{
        return "";
    }
}
相关推荐
j***29481 小时前
对基因列表中批量的基因进行GO和KEGG注释
开发语言·数据库·golang
墨雪不会编程1 小时前
C++基础语法篇五 ——类和对象
java·前端·c++
寻找华年的锦瑟1 小时前
Qt-视频九宫格布局
开发语言·qt
f***R81 小时前
go测试问题记录
开发语言·后端·golang
sunshine6411 小时前
JS实现悬浮可拖拽vue组件封装
开发语言·前端·javascript
v***44671 小时前
PLC(电力载波通信)网络机制介绍
开发语言·网络·php
JienDa1 小时前
JienDa聊PHP:盲盒电商实战中主流PHP框架的协同架构方略
开发语言·架构·php
小邓   ༽1 小时前
C语言课件(非常详细)
java·c语言·开发语言·python·eclipse·c#·c语言课件
JienDa1 小时前
JienDa聊PHP:今日头条仿站实战架构深度解析
开发语言·架构·php