การอ่านไฟล์ MSG

อ่านไฟล์ MSG

mapi_message เป็นจุดเริ่มต้นสำหรับการโหลดและวิเคราะห์ไฟล์ Outlook MSG. การเรียกครั้งเดียวไปยัง from_file() หรือ from_stream() จะอ่านคอนเทนเนอร์ CFB ทั้งหมด, ดึงคุณสมบัติ MAPI ทั้งหมด, และเปิดเผยผ่านเมธอด accessor ที่มีประเภท — ไม่ต้องติดตั้ง Outlook.


โหลดจากเส้นทางไฟล์

ใช้ 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';
}

โหลดจากสตรีม

ใช้ mapi_message::from_stream() เมื่อข้อมูล MSG มาจากซ็อกเก็ตเครือข่าย, ไฟล์บีบอัด, หรือ std::istream ใด ๆ:

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

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

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

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


เข้าถึงคุณสมบัติของข้อความ

mapi_message เปิดเผยคุณสมบัติของข้อความที่พบบ่อยที่สุดในรูปแบบของ getter ที่ตั้งชื่อ:

#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"));

    // Core properties
    std::cout << "Subject:          " << message.subject() << '\n';
    std::cout << "Sender name:      " << message.sender_name() << '\n';
    std::cout << "Sender email:     " << message.sender_email_address() << '\n';
    std::cout << "Internet msg-id:  " << message.internet_message_id() << '\n';
    std::cout << "Message class:    " << message.message_class() << '\n';

    // Body — check html_body() first; fall back to plain body()
    const auto& body = message.html_body().empty()
        ? message.body()
        : message.html_body();
    std::cout << "Body length: " << body.size() << " chars\n";
}

วนซ้ำผู้รับ

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

#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"));

    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';
    }
}

วนซ้ำไฟล์แนบ

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

#include <filesystem>
#include <fstream>
#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"));

    for (const auto& a : message.attachments())
    {
        std::cout << a.filename
                  << "  " << a.mime_type
                  << "  " << a.data.size() << " bytes"
                  << "  embedded=" << (a.is_embedded_message() ? "yes" : "no")
                  << '\n';

        if (!a.is_embedded_message())
        {
            std::ofstream out("extracted_" + a.filename, std::ios::binary);
            out.write(reinterpret_cast<const char*>(a.data.data()),
                      static_cast<std::streamsize>(a.data.size()));
        }
    }
}

เข้าถึงข้อความฝังใน

เมื่อ is_embedded_message() เป็น true ไฟล์แนบจะมีไฟล์ MSG อีกไฟล์หนึ่ง เข้าถึงได้ผ่าน attachment.embedded_message:

#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"));

    for (const auto& a : message.attachments())
    {
        if (a.is_embedded_message() && a.embedded_message != nullptr)
        {
            const auto& inner = *a.embedded_message;
            std::cout << "Embedded subject: " << inner.subject() << '\n';
            inner.save(std::filesystem::path("embedded.msg"));
        }
    }
}

เคล็ดลับและแนวปฏิบัติที่ดีที่สุด

  • ควรส่ง std::ios::binary ไปยัง std::ifstream เสมอเมื่อโหลดไฟล์ MSG.
  • ตรวจสอบ html_body() ก่อน body() — ข้อความที่เป็น HTML เท่านั้นจะเก็บเนื้อหาไว้ในคุณสมบัติ HTML body และปล่อยให้ body() ว่างเปล่า.
  • from_file() โหลดข้อมูลแนบทั้งหมดเข้าสหน่วยความจำ สำหรับไฟล์ MSG ขนาดใหญ่ ให้พิจารณาเปิดคอนเทนเนอร์พื้นฐานด้วย msg_reader เพื่อสำรวจเมตาดาต้าโดยไม่ต้องทำให้ไบต์ของไฟล์แนบเต็มรูปแบบ.
  • พารามิเตอร์ strict ของ from_file(path, strict) และ from_stream(stream, strict) มีค่าเริ่มต้นเป็น false ซึ่งยอมรับความเบี่ยงเบนโครงสร้างเล็กน้อยในไฟล์ MSG ของโลกจริง.
  • อ็อบเจกต์ผู้รับเปิดเผย recipient_type เพื่อแยกแยะรายการ To, Cc, และ Bcc.

ปัญหาทั่วไป

ปัญหาสาเหตุวิธีแก้ไข
msg_exception บนไฟล์ที่ดูเหมือนถูกต้องไฟล์ไม่ใช่คอนเทนเนอร์ OLE CFB ของแท้ตรวจสอบด้วย cfb_reader::from_file() — หากมันก็เกิดข้อผิดพลาดเช่นกัน ไฟล์จึงไม่ใช่ MSG ที่ถูกต้อง
body() คืนสตริงว่างข้อความใช้เนื้อหา HTML เพียงอย่างเดียวใช้ html_body() แทน
recipients() ว่างเปล่าMSG รุ่นเก่าที่ไม่มีตารางผู้รับเข้าถึง display_to ผ่าน get_property_value() ด้วย common_message_property_id::display_to
การเสียหายของสตรีมบน Windowsสตรีมเปิดโดยไม่มี std::ios::binaryเพิ่มแฟล็ก std::ios::binary ให้กับ std::ifstream
การใช้หน่วยความจำสูงสำหรับไฟล์ขนาดใหญ่ข้อมูลแนบทั้งหมดจะถูกโหลดล่วงหน้าใช้ msg_reader สำหรับการเข้าถึงระดับต่ำโดยไม่ต้องทำการสร้างเต็มรูปแบบ

FAQ

from_file() เก็บตัวจัดการไฟล์เปิดอยู่หรือไม่?

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

ฉันจะบอกได้อย่างไรว่าไฟล์แนบเป็นไฟล์ปกติหรือเป็น MSG ที่ฝังอยู่?

เรียก attachment.is_embedded_message(). จะคืนค่า true สำหรับไฟล์ MSG ที่ฝังอยู่; false สำหรับไฟล์แนบปกติ สำหรับข้อความที่ฝังอยู่ ให้เข้าถึงอ็อบเจ็กต์ที่ซ้อนอยู่ผ่าน attachment.embedded_message.

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

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

ไฟล์ MSG แบบ Unicode และ ANSI ทั้งสองรูปแบบได้รับการสนับสนุนหรือไม่?

ใช่. mapi_message รองรับทั้งสตริงแบบ Unicode (ประเภทคุณสมบัติ ptyp_string) และ ANSI (ptyp_string8) unicode_strings() คืนค่า true สำหรับข้อความที่เก็บด้วยคุณสมบัติ Unicode.


API Reference สรุป

คลาส / เมธอดคำอธิบาย
mapi_message::from_file(path)โหลดไฟล์ MSG จาก std::filesystem::path
mapi_message::from_file(path, strict)โหลดด้วยตัวเลือกโหมดเข้มงวด
mapi_message::from_stream(stream)โหลด MSG จาก std::istream
mapi_message::from_stream(stream, strict)โหลดจากสตรีมด้วยตัวเลือกโหมดเข้มงวด
mapi_message::subject()ส่งคืนสตริงหัวข้อข้อความ
mapi_message::body()ส่งคืนส่วนเนื้อหาแบบข้อความธรรมดา
mapi_message::html_body()ส่งคืนส่วนเนื้อหา HTML (ว่างหากไม่มี)
mapi_message::sender_name()ส่งคืนชื่อแสดงของผู้ส่ง
mapi_message::sender_email_address()ส่งคืนที่อยู่อีเมลของผู้ส่ง
mapi_message::internet_message_id()ส่งคืนแฮดเดอร์ Message-ID ของ RFC 2822
mapi_message::message_class()ส่งคืนสตริงคลาสข้อความ MAPI
mapi_message::recipients()ส่งคืนรายการผู้รับ
mapi_message::attachments()คืนรายการไฟล์แนบ
mapi_attachment::is_embedded_message()True หากไฟล์แนบเป็น MSG ที่ฝังอยู่
mapi_message::unicode_strings()True หากข้อความใช้คุณสมบัติของสตริง Unicode

ดูเพิ่มเติม

 ภาษาไทย