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&) { }
}
}
}
}