خواندن فایل‌های MSG

خواندن فایل‌های MSG

mapi_message نقطه ورودی برای بارگذاری و تجزیه فایل‌های Outlook MSG است. یک فراخوانی واحد به from_file() یا from_stream() کل کانتینر CFB را می‌خواند، تمام ویژگی‌های MAPI را استخراج می‌کند و از طریق متدهای دسترسی تایپ‌شده در دسترس می‌گذارد — نیازی به نصب 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 باز کنید. جریان‌های حالت متن در ویندوز انتهای خط را ترجمه می‌کنند و کانتینر CFB را خراب می‌سازند.


دسترسی به ویژگی‌های پیام

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

    // 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"));
        }
    }
}

نکات و بهترین روش‌ها

  • همیشه هنگام بارگذاری فایل‌های MSG، std::ios::binary را به std::ifstream پاس دهید.
  • قبل از body()، html_body() را بررسی کنید — پیام‌های فقط HTML محتوا را در ویژگی بدنه HTML ذخیره می‌کنند و 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
خرابی جریان در ویندوزجریان بدون std::ios::binary باز شدپرچم std::ios::binary را به std::ifstream اضافه کنید
مصرف حافظه بالا برای فایل‌های بزرگتمام داده‌های پیوست به‌صورت پیش‌بارگذاری می‌شونداز msg_reader برای دسترسی سطح پایین بدون تجسم کامل استفاده کنید

FAQ

آیا from_file() دستهٔ فایل را باز نگه می‌دارد؟

نه. فایل باز می‌شود، به‌طور کامل پردازش می‌شود و قبل از بازگشت متد بسته می‌شود. پس از فراخوانی می‌توانید فایل منبع را جابجا یا حذف کنید.

چگونه می‌توانم تشخیص دهم که یک ضمیمه یک فایل است یا یک MSG توکار؟

متد attachment.is_embedded_message() را فراخوانی کنید. برای فایل‌های MSG توکار true برگردانده می‌شود؛ برای ضمیمه‌های فایل عادی false. برای پیام‌های توکار، از طریق attachment.embedded_message به شیء تو در تو دسترسی پیدا کنید.

تفاوت بین from_file() و استفاده از msg_reader چیست؟

mapi_message::from_file() سطح بالای API است — کل پیام را تجزیه می‌کند و ویژگی‌ها را به‌صورت فیلدهای تایپ‌دار ارائه می‌دهد. msg_reader خوانندهٔ سطح پایین است که دسترسی به ساختار خام کانتینر CFB را فراهم می‌کند و زمانی مفید است که نیاز به بررسی چیدمان پیام بدون تجزیه تمام ویژگی‌های MAPI دارید.

آیا هر دو نوع فایل MSG یونیکد و ANSI پشتیبانی می‌شوند؟

بله. mapi_message هر دو رشتهٔ یونیکد (نوع ویژگی ptyp_string) و ANSI (ptyp_string8) را مدیریت می‌کند. unicode_strings() برای پیام‌های ذخیره‌شده با ویژگی‌های یونیکد، true برمی‌گرداند.


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()درست اگر پیوست یک MSG توکار باشد
mapi_message::unicode_strings()درست اگر پیام از ویژگی‌های رشته Unicode استفاده کند

همچنین ببینید:

 فارسی