#include "File_Helper.h" #include "../system/export.h" #include namespace Psc { void File_Gather_Simple::init(std::string_view path, size_t size) { this->buffer_size = size; abs_path = Psc::get_abs_path(path); ofs.open(abs_path, std::ios::binary | std::ios::app); if (!ofs) throw std::runtime_error("Failed to open file: " + abs_path); std::filesystem::permissions(abs_path, std::filesystem::perms::owner_read | std::filesystem::perms::owner_write | std::filesystem::perms::group_read, std::filesystem::perm_options::replace); buffer.reserve(buffer_size); } File_Gather_Simple::File_Gather_Simple(std::string_view path, size_t buffer_size) { init(path, buffer_size); } void File_Gather_Simple::append(const std::uint8_t *data, size_t size) { if (size > buffer_size) { flush(); ofs.write(reinterpret_cast(data), size); return; } if (buffer.size() + size > buffer_size) { flush(); } buffer.append(reinterpret_cast(data), size); } File_Gather_Simple::~File_Gather_Simple() { flush(); ofs.close(); } void File_Gather_Simple::flush() { if (!buffer.empty()) { ofs.write(buffer.data(), buffer.size()); buffer.clear(); } ofs.flush(); } // 回放类 File_Player::File_Player(std::string_view path) { open(path); } void File_Player::open(std::string_view path) { close(); auto path_string = std::string(path); total_size_ = std::filesystem::file_size(path_string); ifs.open(path_string, std::ios::binary); if (!ifs) throw std::runtime_error("Failed to open file: " + path_string); } void File_Player::close() { if (ifs.is_open()) ifs.close(); } size_t File_Player::read(std::uint8_t *buffer, size_t size) { if (!ifs) return 0; ifs.read(reinterpret_cast(buffer), size); return static_cast(ifs.gcount()); } bool File_Player::eof() const { return ifs.eof(); } void File_Player::rewind() { ifs.clear(); ifs.seekg(0, std::ios::beg); } std::uint64_t File_Player::total_size() const { return total_size_; } std::uint64_t File_Player::current_offset() { if (!ifs) return 0; auto pos = ifs.tellg(); if (pos < 0) return total_size_; // EOF 后 tellg 可能为 -1 return static_cast(pos); } std::uint64_t File_Player::remaining_size() { auto cur = current_offset(); if (cur >= total_size_) return 0; return total_size_ - cur; } double File_Player::progress() { if (total_size_ == 0) return 0.0; return static_cast(current_offset()) / static_cast(total_size_); } File_Gather::File_Gather(std::string_view path, size_t buffer_size) : gather_file(path, buffer_size) {} void File_Gather::init(std::string_view path, size_t buffer_size) { gather_file.init(path, buffer_size); } void File_Gather::append(const std::uint8_t *data, size_t size) { append_speed.update(size); append_value.update(static_cast(size)); gather_file.append(data, size); } } // namespace Psc