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 "";
    }
}
相关推荐
凉茶钱1 小时前
红黑树:用“颜色”换“平衡”,set 与 map 的底层发动机
开发语言·c++·红黑树
高冷小鱼殿下1 小时前
内部类Lambda与枚举
java·开发语言
shelly聊外贸2 小时前
WhatsApp 聊天记录如何导出为 CSV?使用 Python 进行数据分析
开发语言·python·数据分析
octopus_c2 小时前
C++ 模板详解:函数模板、类模板、特化与分离编译
开发语言·c++·算法
東隅已逝,桑榆非晚2 小时前
算法1. 双指针法-移动零
c++·算法
椒颜皮皮虾྅3 小时前
让文档不止于文字:DeploySharp + PP-Structure,打通版面分析与表格重建
开发语言·学习·c#·.net·cuda
Eider19984 小时前
Python基础知识之并发相关-2
开发语言·前端·python
第九序言T4 小时前
Python 数据处理进阶(二十二)用 Pandas 做一次完整的用户行为分析
开发语言·python·数据分析·pandas
云和数据.ChenGuang4 小时前
再论深拷贝和浅拷贝
开发语言·人工智能·python·1024程序员节
悠仁さん4 小时前
【C++】set map 使用
java·前端·c++