FileStream C++

HPP

cpp 复制代码
#pragma once

#include <chtrader/io/Stream.h>

namespace chtrader 
{
    namespace io 
    {
        class FileStream : public virtual Stream
        {
        public:
            // 构造函数:打开指定路径的文件
            // @param path 文件路径
            // @param mode 打开模式
            FileStream(const chtrader::string& path, std::ios_base::openmode mode) noexcept;
        
            // 析构函数:关闭文件流
            ~FileStream() noexcept override;
        
            // 检查是否支持定位操作
            virtual bool                        CanSeek() noexcept override;
        
            // 检查是否支持读取操作
            virtual bool                        CanRead() noexcept override;
        
            // 检查是否支持写入操作
            virtual bool                        CanWrite() noexcept override;
        
            // 获取当前流位置
            virtual  int64_t                    GetPosition() noexcept override;
        
            // 获取流总长度
            virtual  int64_t                    GetLength() noexcept override;
        
            // 设置流位置
            virtual bool                        Seek(int64_t offset, SeekOrigin loc) noexcept override;
        
            // 直接设置流位置到指定偏移
            virtual bool                        SetPosition(int64_t position) noexcept override;
        
            // 设置流长度
            virtual bool                        SetLength(int64_t value) noexcept override;

            // 设置缓冲区               
            virtual bool                        SetBuffer(const void* buffer, int buffer_size) noexcept;
        
            // 写入单个字节
            virtual bool                        WriteByte(uint8_t value) noexcept override;
        
            // 写入数据块
            virtual bool                        Write(const void* buffer, int64_t offset, int64_t count) noexcept override;
        
            // 读取单个字节
            virtual  int64_t                    ReadByte() noexcept override;
        
            // 读取数据块
            virtual  int64_t                    Read(void* buffer, int64_t offset, int64_t count) noexcept override;

            // 释放资源
            void                                Dispose() noexcept override;

        private:        
            std::fstream                        m_fs;    // 文件流对象
            std::ios_base::openmode             m_mode;  // 打开模式标志
        };
    }
}

CPP

cpp 复制代码
#include <chtrader/io/FileStream.h>

#include <system_error>

namespace chtrader
{
    namespace io
    {
        FileStream::FileStream(const chtrader::string& path, std::ios_base::openmode mode) noexcept
            : m_fs(stl::transform<std::string>(path), mode | std::ios::binary), m_mode(mode)
        {
            // 启用异常
            // m_fs.exceptions(std::ios::failbit | std::ios::badbit); 
        }

        FileStream::~FileStream() noexcept
        {
            if (m_fs.is_open()) 
            {
                m_fs.close();  // 确保文件关闭
            }
        }

        bool FileStream::CanSeek() noexcept
        {
            return (m_mode & (std::ios::in | std::ios::out)) != 0;
        }

        bool FileStream::CanRead() noexcept
        {
            return (m_mode & std::ios::in) && m_fs.good();
        }

        bool FileStream::CanWrite() noexcept
        {
            return (m_mode & std::ios::out) && m_fs.good();
        }

        int64_t FileStream::GetPosition() noexcept
        {
            if (CanRead()) 
            {
                return static_cast<int64_t>(m_fs.tellg());
            }

            if (CanWrite()) 
            {
                return static_cast<int64_t>(m_fs.tellp());
            }

            return -1;
        }

        int64_t FileStream::GetLength() noexcept
        {
            std::streampos current = m_fs.tellg();
            m_fs.seekg(0, std::ios::end);

            int64_t length = static_cast<int64_t>(m_fs.tellg());
            m_fs.seekg(current);
            
            return length;
        }

        bool FileStream::Seek(int64_t offset, SeekOrigin loc) noexcept
        {
            if (!m_fs.is_open())
            {
                return false;
            }

            std::ios_base::seekdir dir;
            switch (loc)
            {
            case SeekOrigin::Begin:
                dir = std::ios::beg;
                break;
            case SeekOrigin::Current:
                dir = std::ios::cur;
                break;
            case SeekOrigin::End:
                dir = std::ios::end;
                break;
            default:
                return false;
            }

            bool result = false;
            if (CanRead())
            {
                result = !m_fs.seekg(offset, dir).fail();
            }

            if (CanWrite()) 
            {
                result = !m_fs.seekp(offset, dir).fail();
            }

            return result;
        }

        bool FileStream::SetPosition(int64_t position) noexcept
        {
            return Seek(position, SeekOrigin::Begin);
        }

        bool FileStream::SetLength(int64_t value) noexcept
        {
            if (value < 0) 
            {
                return false;
            }

            if (CanWrite()) 
            {
                m_fs.write("", 0);  // 确保处于输出模式
                m_fs.flush();
                return !m_fs.fail();
            }

            return false;
        }

        bool FileStream::SetBuffer(const void* buffer, int buffer_size) noexcept
        {
            if (NULL == buffer || buffer_size < 1)
            {
                return false;
            }

            if (!m_fs.is_open())
            {
                return false;
            }

            auto rdbuf = m_fs.rdbuf();
            if (NULL == rdbuf)
            {
                return false;
            }
            
            rdbuf->pubsetbuf((char*)(buffer), 1024 * 1024);
            return true;
        }

        bool FileStream::WriteByte(uint8_t value) noexcept
        {
            if (!CanWrite()) 
            {
                return false;
            }

            m_fs.write(reinterpret_cast<const char*>(&value), 1);
            return !m_fs.fail();
        }

        bool FileStream::Write(const void* buffer, int64_t offset, int64_t count) noexcept
        {
            if (!CanWrite() || offset < 0 || count <= 0) 
            {
                return false;
            }

            m_fs.write(static_cast<const char*>(buffer), count);
            return !m_fs.fail();
        }

        int64_t FileStream::ReadByte() noexcept
        {
            if (!CanRead()) 
            {
                return -1;
            }

            char byte;
            m_fs.read(&byte, 1);

            return m_fs.gcount() > 0 ? static_cast<uint8_t>(byte) : -1;
        }

        int64_t FileStream::Read(void* buffer, int64_t offset, int64_t count) noexcept
        {
            if (!CanRead() || offset < 0 || count <= 0)
            {
                return -1;
            }

            m_fs.read(static_cast<char*>(buffer), count);
            return m_fs.gcount();
        }

        void FileStream::Dispose() noexcept
        {
            if (m_fs.is_open())
            {
                try 
                {
                    m_fs.close();
                }
                catch (const std::exception&) { }
            }
        }
    }
}
相关推荐
Bruce_Liuxiaowei20 分钟前
Python 实例赋值遮蔽类属性:一个从不报错的静默陷阱
开发语言·python·语法糖
aramae2 小时前
MySQL内置函数(7)
开发语言·笔记·后端·mysql·其他
汉克老师2 小时前
CSP-J 2026 初赛试题解析(第一部分:选择题(8-15))精讲
c++·csp-j·小学生·学c++编程
wabs6663 小时前
关于二叉树【力扣572.另一棵树的子树的思考】
数据结构·c++·算法·leetcode·二叉树
风合星语4 小时前
2026 ROS 2 Lyrical C++ 入门(五):Action 实战——任务反馈、取消与超时处理
c++·机器人·ros2·异步编程·lyrical
91刘仁德4 小时前
C++ 继承和多态 设计模式
c语言·c++·笔记
码行山野赴时序归途5 小时前
链表家族收官篇:循环链表
c语言·开发语言·数据结构·链表
景熙55235 小时前
单体项目编写思路和落地形式
java·开发语言
库玛西5 小时前
哈夫曼树与前缀编码:数据压缩的贪心核心
c语言·c++·笔记·考研
别动我齐刘海5 小时前
ROS2 Jazzy + C++ 实战路线——进阶学习3
c++·人工智能·vscode·python·算法·机器学习·机器人