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 小时前
PHP里面的抽象类和接口类
开发语言·php
咖啡の猫7 小时前
Python字典推导式
开发语言·python
leiming67 小时前
C++ vector容器
开发语言·c++·算法
SystickInt7 小时前
C语言 strcpy和memcpy 异同/区别
c语言·开发语言
CS Beginner8 小时前
【C语言】windows下编译mingw版本的glew库
c语言·开发语言·windows
FJW0208148 小时前
Python_work4
开发语言·python
大学生资源网8 小时前
java毕业设计之儿童福利院管理系统的设计与实现(源码+)
java·开发语言·spring boot·mysql·毕业设计·源码·课程设计
JasmineWr8 小时前
JVM栈空间的使用和优化
java·开发语言
Poetinthedusk9 小时前
C#实现图片统一位深
开发语言·c#
吴佳浩 Alben9 小时前
Python入门指南(四)
开发语言·后端·python