From 1683996d4381227de9b5a5574d9383af55e145fe Mon Sep 17 00:00:00 2001 From: Quella777 <2892744389@qq.com.com> Date: Wed, 13 Aug 2025 11:33:31 +0800 Subject: [PATCH] update --- include/Netra.hpp | 17 ++++------ src/Netra.cpp | 86 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 65 insertions(+), 38 deletions(-) diff --git a/include/Netra.hpp b/include/Netra.hpp index 8e6b1bf..0515464 100644 --- a/include/Netra.hpp +++ b/include/Netra.hpp @@ -150,15 +150,12 @@ namespace QCL bool appendBinary(const std::vector &data); /** - * @brief 计算第一个指定字节序列前的字节数(包含该字节序列本身) - * - * 例如:文件内容是 "ABC***--***XYZ",模式是 "***--***" - * 返回值应为 11("ABC"=3字节 + "***--***"=8字节)。 - * - * @param pattern 要查找的字节模式(支持多字节) - * @return long 字节数(包含匹配模式本身),未找到返回 -1 + * @brief 计算第一个指定字节序列前的字节数 + * @param pattern 要查找的字节序列 + * @param includePattern true 表示返回值包含 pattern 自身长度,false 表示不包含 + * @return size_t 字节数,如果文件没打开或 pattern 为空则返回 0 */ - long countBytesBeforePattern(const std::string &pattern); + size_t countBytesBeforePattern(const std::string &pattern, bool includePattern = false); private: std::string filePath_; ///< 文件路径 @@ -259,9 +256,9 @@ namespace QCL /** * @brief 获取指定字节序列前的字节数(包含该字节序列) * @param marker 要查找的字节序列(可能不止一个字节) - * @return 如果找到,返回前面部分字节数;找不到返回全文字节数 + * @return 如果找到,返回前面部分字节数;找不到返回0 */ - size_t GetBytesBefore(const std::string &marker); + size_t GetBytesBefore(const std::string &marker, bool includeMarker = false); /** * @brief 检查文件是否存在 diff --git a/src/Netra.cpp b/src/Netra.cpp index eac64bf..3d09b43 100644 --- a/src/Netra.cpp +++ b/src/Netra.cpp @@ -306,37 +306,44 @@ namespace QCL return true; } - /** - * @brief 计算第一个指定字节序列前的字节数(包含该字节序列本身) - */ - long WriteFile::countBytesBeforePattern(const std::string &pattern) + size_t WriteFile::countBytesBeforePattern(const std::string &pattern, bool includePattern) { std::lock_guard lock(writeMutex_); if (pattern.empty()) - return -1; + return 0; - std::ifstream file(filePath_, std::ios::binary); // 二进制模式防止编码干扰 + std::ifstream file(filePath_, std::ios::binary); if (!file.is_open()) - return -1; + return 0; - // 将整个文件读入内存 - std::vector buffer((std::istreambuf_iterator(file)), - std::istreambuf_iterator()); - file.close(); + file.clear(); // 清除EOF和错误状态 + file.seekg(0, std::ios::beg); // 回到文件开头 - // 在 buffer 中查找 pattern - auto it = std::search(buffer.begin(), buffer.end(), - pattern.begin(), pattern.end()); + const size_t chunkSize = 4096; + std::string buffer; + buffer.reserve(chunkSize * 2); - if (it == buffer.end()) + size_t totalRead = 0; + char chunk[chunkSize]; + + while (file.read(chunk, chunkSize) || file.gcount() > 0) { - return -1; // 没找到 + buffer.append(chunk, file.gcount()); + size_t pos = buffer.find(pattern); + if (pos != std::string::npos) + { + return includePattern ? (pos + pattern.size()) : pos; + } + + // 保留末尾部分,避免 buffer 无限增长 + if (buffer.size() > pattern.size()) + buffer.erase(0, buffer.size() - pattern.size()); + + totalRead += file.gcount(); } - // 计算从开头到 pattern 结束的字节数 - size_t pos = std::distance(buffer.begin(), it); - return static_cast(pos + pattern.size()); + return 0; // 没找到 pattern,返回0 } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -419,21 +426,44 @@ namespace QCL return buffer; } - size_t ReadFile::GetBytesBefore(const std::string &marker) + size_t ReadFile::GetBytesBefore(const std::string &marker, bool includeMarker) { std::lock_guard lock(mtx_); + if (!file_.is_open() && !Open()) return 0; - std::ostringstream ss; - ss << file_.rdbuf(); - std::string content = ss.str(); + file_.clear(); // 清除EOF和错误状态 + file_.seekg(0, std::ios::beg); // 回到文件开头 - size_t pos = content.find(marker); - if (pos != std::string::npos) - return pos + marker.size(); - else - return content.size(); + const size_t chunkSize = 4096; + std::string buffer; + buffer.reserve(chunkSize * 2); + + size_t totalRead = 0; + char chunk[chunkSize]; + + while (file_.read(chunk, chunkSize) || file_.gcount() > 0) + { + buffer.append(chunk, file_.gcount()); + size_t pos = buffer.find(marker); + if (pos != std::string::npos) + { + // 如果 includeMarker 为 true,返回包含 marker 的长度 + if (includeMarker) + return pos + marker.size(); + else + return pos; + } + + // 保留末尾部分,避免 buffer 无限增长 + if (buffer.size() > marker.size()) + buffer.erase(0, buffer.size() - marker.size()); + + totalRead += file_.gcount(); + } + + return 0; } bool ReadFile::FileExists() const