วิธีอ่านไฟล์ MSG ใน C++

วิธีอ่านไฟล์ MSG ใน C++

Aspose.Email FOSS สำหรับ C++ ให้คุณเปิดและแยกวิเคราะห์ไฟล์ Outlook MSG ด้วยการเรียกฟังก์ชันเดียว mapi_message::from_file() และ mapi_message::from_stream() โหลดข้อความเต็ม — หัวเรื่อง, เนื้อหา, ผู้ส่ง, ผู้รับ, และไฟล์แนบ — ไปยังอ็อบเจ็กต์ในหน่วยความจำโดยไม่ต้องพึ่งพา Outlook หรือ COM.

ขั้นตอนที่ 1 — ตั้งค่าโปรเจกต์

คัดลอกรีโพสทอรีและเพิ่มเข้าไปใน CMakeLists.txt ของคุณ:

git clone https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-Cpp.git
add_subdirectory(Aspose.Email-FOSS-for-Cpp)
target_link_libraries(your_target PRIVATE AsposeEmailFoss::AsposeEmailFoss)

ขั้นตอนที่ 2 — รวม Header

#include "aspose/email/foss/msg/mapi_message.hpp"

Header เดียวนี้ให้ mapi_message และประเภทสนับสนุนทั้งหมดในเนมสเปซ aspose::email::foss::msg.


ขั้นตอนที่ 3 — โหลดข้อความจากเส้นทางไฟล์

ใช้ mapi_message::from_file() เมื่อคุณมี std::filesystem::path:

#include <filesystem>
#include <iostream>
#include "aspose/email/foss/msg/mapi_message.hpp"

int main()
{
    const auto message = aspose::email::foss::msg::mapi_message::from_file(
        std::filesystem::path("sample.msg"));

    std::cout << "Subject: " << message.subject() << '\n';
    std::cout << "From:    " << message.sender_name()
              << " <" << message.sender_email_address() << ">\n";
    std::cout << "Body:    " << message.body() << '\n';
}

ขั้นตอนที่ 4 — โหลดข้อความจากสตรีม

ใช้ mapi_message::from_stream() เพื่อพาร์สจาก std::istream ใด ๆ — มีประโยชน์สำหรับการประมวลผลข้อมูล MSG ที่ได้รับผ่านเครือข่ายหรือจากบัฟเฟอร์ในหน่วยความจำ:

#include <fstream>
#include <iostream>
#include "aspose/email/foss/msg/mapi_message.hpp"

int main()
{
    std::ifstream input("sample.msg", std::ios::binary);
    auto message = aspose::email::foss::msg::mapi_message::from_stream(input);

    std::cout << "Subject: " << message.subject() << '\n';
}

ควรเปิดสตรีมด้วย std::ios::binary เสมอเพื่อป้องกันการแปลงจบบรรทัดของ Windows ทำให้คอนเทนเนอร์ CFB เสียหาย.


ขั้นตอนที่ 5 — วนผ่านผู้รับ

message.recipients() ส่งคืน std::vector ของอ็อบเจกต์ผู้รับ, แต่ละอ็อบเจกต์มีฟิลด์ display_name, email_address, และ recipient_type:

#include <fstream>
#include <iostream>
#include "aspose/email/foss/msg/mapi_message.hpp"

int main()
{
    std::ifstream input("sample.msg", std::ios::binary);
    auto message = aspose::email::foss::msg::mapi_message::from_stream(input);

    for (std::size_t i = 0; i < message.recipients().size(); ++i)
    {
        const auto& r = message.recipients()[i];
        std::cout << "[" << (i + 1) << "] "
                  << r.display_name << " <" << r.email_address << ">"
                  << " type=" << r.recipient_type << '\n';
    }
}

ขั้นตอนที่ 6 — วนผ่านไฟล์แนบ

message.attachments() ส่งคืน std::vector ของอ็อบเจกต์ไฟล์แนบ. แต่ละไฟล์แนบเปิดเผย filename, mime_type, data (ไบต์ดิบ), content_id, และพรีดิเคต is_embedded_message():

#include <fstream>
#include <iostream>
#include "aspose/email/foss/msg/mapi_message.hpp"

int main()
{
    std::ifstream input("sample.msg", std::ios::binary);
    auto message = aspose::email::foss::msg::mapi_message::from_stream(input);

    for (std::size_t i = 0; i < message.attachments().size(); ++i)
    {
        const auto& a = message.attachments()[i];
        std::cout << "[" << (i + 1) << "] "
                  << a.filename << "  mime=" << a.mime_type
                  << "  bytes=" << a.data.size()
                  << "  embedded=" << (a.is_embedded_message() ? "yes" : "no")
                  << '\n';
    }
}

ปัญหาทั่วไปและการแก้ไข

Empty body() หลังจากโหลดแล้ว. บางข้อความเก็บข้อความไว้เฉพาะในคุณสมบัติ body ของ HTML ตรวจสอบ message.html_body() when message.body() ส่งคืนสตริงว่าง.

สตรีมเปิดโดยไม่มี std::ios::binary. บน Windows สตรีมแบบข้อความจะแปลงลำดับอักขระ CRLF ทำให้ข้อมูล CFB แบบไบนารีเสียหายอย่างเงียบๆ ควรเปิดไฟล์ MSG เสมอด้วย std::ios::binary.

msg_exception ถูกโยนสำหรับไฟล์ที่ดูเหมือนถูกต้อง. ตรวจสอบว่าไฟล์เป็น MSG ของแท้ (OLE Compound File) ไฟล์ที่บันทึกโดยเครื่องมือส่งออกบางอย่างอาจเป็นข้อความธรรมดาหรือ MIME และไม่สามารถแยกวิเคราะห์ได้โดย mapi_message::from_file().

recipients() ส่งคืนเวกเตอร์ว่าง. ไฟล์ MSG เก่า บางครั้งละเว้นตารางผู้รับ แต่จัดเก็บผู้รับที่แสดงใน display_to คุณสมบัติ MAPI เข้าถึงได้ผ่าน message.get_property_value() with common_message_property_id::display_to and property_type_code::ptyp_string.

ข้อมูลไฟล์แนบขนาดใหญ่ในหน่วยความจำ. mapi_message::from_file() and from_stream() โหลดข้อความทั้งหมดรวมถึงไบต์ของไฟล์แนบทั้งหมด สำหรับไฟล์ขนาดใหญ่ ให้เปิดคอนเทนเนอร์พื้นฐานด้วย msg_reader และตรวจสอบสตรีมไฟล์แนบโดยไม่ต้องทำให้เต็มรูปแบบ.

คำถามที่พบบ่อย

ความแตกต่างระหว่าง from_file() กับ from_stream() คืออะไร?

ทั้งสองสร้างอ็อบเจกต์ mapi_message ที่เหมือนกัน. from_file() ยอมรับ std::filesystem::path และเปิดไฟล์ภายใน. from_stream() อ่านจาก std::istream ใด ๆ ที่คุณให้ — มีประโยชน์เมื่อข้อมูล MSG อยู่ในหน่วยความจำแล้วหรือกำลังมาถึงผ่านซ็อกเก็ต.

from_file() เปิดไฟล์ไว้หลังจากโหลดหรือไม่?

ไม่. ไฟล์จะถูกเปิด, แปลงทั้งหมดเข้าไปในหน่วยความจำ, แล้วปิดก่อนที่ from_file() จะคืนค่า. คุณสามารถย้ายหรือทำลายไฟล์ต้นฉบับได้ทันทีหลังจากเรียกใช้.

ฉันสามารถอ่านไฟล์ MSG ที่สร้างโดย Outlook บน macOS หรือ Linux ได้หรือไม่?

ใช่. รูปแบบ MSG (OLE Compound File + MAPI properties) สามารถพกพาข้ามระบบปฏิบัติการได้. ไฟล์ .msg ใด ๆ ที่ผลิตโดย Outlook เวอร์ชันใดก็สามารถเปิดได้ด้วย mapi_message::from_file().

ฉันจะอ่านเนื้อหา HTML อย่างไร?

เรียก message.html_body(). หากข้อความถูกสร้างด้วยเนื้อหาแบบ plain-text เท่านั้น, จะคืนค่าเป็นสตริงว่าง. message.body() จะคืนค่าเนื้อหาแบบ plain-text.

strict mode เป็นค่าเริ่มต้นหรือไม่?

mapi_message::from_file(path, strict) และ from_stream(stream, strict) ยอมรับบูลีน strict ตัวเลือก. ค่าเริ่มต้นคือ false, ซึ่งยอมรับความเบี่ยงเบนเชิงโครงสร้างเล็กน้อยในไฟล์ MSG ของโลกจริง.

ดูเพิ่มเติม

 ภาษาไทย