#pragma once #define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include // Windows 内存映射文件封装类 class CMappedFile { public: explicit CMappedFile(const char* path) { m_hFile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr); if (m_hFile == INVALID_HANDLE_VALUE) return; m_hMapping = CreateFileMappingA(m_hFile, nullptr, PAGE_READONLY, 0, 0, nullptr); if (!m_hMapping) { CloseHandle(m_hFile); m_hFile = INVALID_HANDLE_VALUE; return; } m_data = static_cast(MapViewOfFile(m_hMapping, FILE_MAP_READ, 0, 0, 0)); } ~CMappedFile() { if (m_data) UnmapViewOfFile(m_data); if (m_hMapping) CloseHandle(m_hMapping); if (m_hFile != INVALID_HANDLE_VALUE) CloseHandle(m_hFile); } bool IsValid() const { return m_data != nullptr; } const char* Data() const { return m_data; } size_t Size() const { LARGE_INTEGER li{}; li.LowPart = GetFileSize(m_hFile, reinterpret_cast(&li.HighPart)); return li.QuadPart; } private: HANDLE m_hFile = INVALID_HANDLE_VALUE; HANDLE m_hMapping = nullptr; const char* m_data = nullptr; }; //光斑RawData多线程解析 class BeamCsvParserMT { public: unsigned char* Load(const char* path, int& width, int& height) { m_file = std::make_unique(path); if (!m_file->IsValid()) { width = height = 0; return nullptr; } size_t cols = DetectColumnCount(m_file->Data()); m_threadResults.resize(1); m_threadResults[0].reserve(cols*cols); ParseBlock(0, m_file->Size(), m_threadResults[0]); size_t total = 0; for (auto& v : m_threadResults) total += v.size(); unsigned char* result = new unsigned char[total]; unsigned char* dst = result; for (auto& v : m_threadResults) { memcpy(dst, v.data(), v.size()); dst += v.size(); } height = static_cast(total / cols); width = static_cast(cols); return result; } private: // =============================== // 内部工具函数 // =============================== size_t DetectColumnCount(const char* data) const { size_t cols = 1; for (const char* p = data; *p != '\n' && *p != '\r' && *p != '\0'; ++p) { if (*p == ',') ++cols; } return cols; } std::vector>SplitIntoLineBlocks(const char* data, size_t size, size_t threadCount, size_t & Rows) const { std::vector offsets{ 0 };//声明并放入一个0值 for (size_t i = 0; i < size; ++i) { if (data[i] == '\n') offsets.emplace_back(i + 1); } if (offsets.back() < size) offsets.emplace_back(size); Rows = offsets.size() - 1; size_t linesPerThread = Rows / threadCount; std::vector> blocks; for (size_t t = 0; t < threadCount; ++t) { size_t start = offsets[t * linesPerThread]; size_t end = (t == threadCount - 1) ? offsets.back() : offsets[(t + 1) * linesPerThread]; blocks.emplace_back(start, end); } return blocks; } void ParseBlock(size_t start, size_t end, std::vector& out) const { const char* p = m_file->Data() + start; const char* blockEnd = m_file->Data() + end; const char* fieldStart = p; char sVal[32]{ 0 }; while (p < blockEnd) { if (*p == ',' || *p == '\n' || *p == '\r') { memset(sVal, 0, 32); memcpy(sVal, fieldStart, p - fieldStart); out.emplace_back(static_cast(min(atoi(sVal), 254))); if (*p == '\r' && (p + 1 < blockEnd && *(p + 1) == '\n')) ++p; fieldStart = p + 1; } ++p; } } private: std::unique_ptr m_file; std::vector> m_threadResults; };