تبدیل EML و MSG

تبدیل EML و MSG

Aspose.Email FOSS برای C++ به‌صورت دوطرفه تبدیل می‌کند بین EML (RFC 5322 / MIME) و MSG قالب‌های (Outlook MAPI) با استفاده از mapi_message. مسیر تبدیل به این صورت است: load_from_eml() → در حافظه mapi_messagesave() برای EML→MSG، و from_file() / from_stream()save_to_eml() برای MSG→EML.


تبدیل EML به MSG

فایل EML را با mapi_message::load_from_eml() بارگذاری کنید، سپس با save() به MSG سریال‌سازی کنید:

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

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

    std::cout << "Subject: " << message.subject() << '\n';
    message.save(std::filesystem::path("converted.msg"));
    std::cout << "Saved converted.msg\n";
}

load_from_eml() ساختار MIME را تجزیه می‌کند و موضوع MAPI، بدنه متن ساده، بدنه HTML، هویت فرستنده، فهرست دریافت‌کنندگان و تمام بخش‌های پیوست را پر می‌کند.


تبدیل MSG به EML

فایل MSG را با mapi_message::from_file() بارگذاری کنید، سپس save_to_eml() را فراخوانی کنید:

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

    message.save_to_eml(std::filesystem::path("exported.eml"));
    std::cout << "Saved exported.eml\n";
}

تبدیل مبتنی بر جریان

تمام چهار روش مرتبط، بارگذاری‌های std::istream / std::ostream را برای پردازش به سبک خط لوله می‌پذیرند بدون اینکه به سیستم فایل دست بزنند:

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

int main()
{
    // EML → MSG via streams
    std::ifstream eml_in("message.eml", std::ios::binary);
    const auto message = aspose::email::foss::msg::mapi_message::load_from_eml(eml_in);

    std::ofstream msg_out("converted.msg", std::ios::binary);
    message.save(msg_out);

    // MSG → EML via streams
    std::ifstream msg_in("converted.msg", std::ios::binary);
    const auto reloaded = aspose::email::foss::msg::mapi_message::from_stream(msg_in);

    std::ofstream eml_out("roundtrip.eml", std::ios::binary);
    reloaded.save_to_eml(eml_out);
}

همیشه جریان‌ها را با std::ios::binary باز کنید. جریان‌های حالت متنی انتهای خط‌ها را در ویندوز ترجمه می‌کنند و داده‌های باینری CFB را خراب می‌سازند.


تبدیل درون‌حافظه‌ای (بایت‌ها)

save() و save_to_eml() هر دو بارگذاری‌های بدون آرگومان دارند که std::vector<std::uint8_t> را برمی‌گردانند. برای جلوگیری از تمام ورودی/خروجی سیستم فایل از این‌ها استفاده کنید:

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

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

    const std::vector<std::uint8_t> msg_bytes  = message.save();
    const std::vector<std::uint8_t> eml_bytes  = message.save_to_eml();

    // Write to a database, network socket, or other destination...
}

تبدیل دسته‌ای پوشه

یک پوشه را با std::filesystem::directory_iterator پیمایش کنید تا تمام فایل‌های .eml را در یک عبور تبدیل کنید:

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

int main()
{
    const std::filesystem::path input_dir("emails/eml");
    const std::filesystem::path output_dir("emails/msg");
    std::filesystem::create_directories(output_dir);

    for (const auto& entry : std::filesystem::directory_iterator(input_dir))
    {
        if (entry.path().extension() != ".eml")
            continue;

        const auto message = aspose::email::foss::msg::mapi_message::load_from_eml(
            entry.path());

        auto out_path = output_dir / entry.path().filename();
        out_path.replace_extension(".msg");
        message.save(out_path);

        std::cout << "Converted: " << entry.path().filename() << '\n';
    }
}

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

  • تمام جریان‌های فایل را با std::ios::binary باز کنید — هم برای ورودی و هم برای خروجی.
  • در صورتی که مسیر دارید، به جای overload جریان، load_from_eml(path) را ترجیح دهید؛ overload مسیر باز کردن فایل را به‌صورت داخلی مدیریت می‌کند و کمی ساده‌تر است.
  • از overloadهای بایت (save() و save_to_eml() بدون آرگومان) زمانی که داده‌ها را بین سرویس‌ها لوله‌کشی می‌کنید، استفاده کنید تا از فایل‌های موقت جلوگیری شود.
  • موضوع، متن، متن HTML، فرستنده، دریافت‌کنندگان و پیوست‌های MIME همگی در طول مسیر کامل حفظ می‌شوند.
  • پرچم‌های IMAP، هدرهای مسیریابی و محتوای رمزگذاری‌شده به‌صورت TNEF در تبدیل منتقل نمی‌شوند.

مسائل رایج

مسئلهدلیلاصلاح
load_from_eml در یک فایل معتبر خطا می‌دهدپایان خطوط غیر CRLF در EMLاطمینان حاصل کنید که EML از CRLF مطابق RFC 5322 استفاده می‌کند؛ برخی ابزارهای خروجی فقط LF می‌نویسند
پیوست‌های گمشده پس از تبدیل EML → MSGرمزگذاری پیوست MIME غیر استانداردتأیید کنید که EML از multipart/mixed با Content-Disposition: attachment استاندارد استفاده می‌کند
بدنهٔ خالی HTML پس از MSG → EMLمنبع MSG فقط دارای بدنهٔ متن ساده استبررسی کنید message.html_body()؛ اگر خالی باشد، فقط متن ساده ذخیره شده است
خروجی استریم خراب استجریان در حالت متنی باز شدهمیشه از std::ios::binary استفاده کنید
موضوع توالی‌های ?= را نشان می‌دهدکلمه‌کدگذاری شده RFC 2047 در EML اصلیبا یک کتابخانه RFC 2047 رمزگشایی کنید؛ کتابخانه فرم رمزگذاری‌شده را حفظ می‌کند

FAQ

آیا تبدیل EML → MSG متن HTML را حفظ می‌کند؟

بله. یک بخش MIME text/html در ویژگی بدنه MAPI HTML ذخیره می‌شود و پس از بارگذاری از طریق message.html_body() قابل دسترسی است.

آیا پیوست‌ها در هر دو جهت حفظ می‌شوند؟

بله. تمام بخش‌های پیوست MIME از طریق فهرست پیوست mapi_message منتقل می‌شوند. داده‌های باینری پیوست به صورت attachment.data (یک std::vector<std::uint8_t>) در دسترس است.

آیا می‌توانم یک فایل EML را به‌صورت همزمان به چندین قالب خروجی تبدیل کنم؟

بله. EML را یک بار با load_from_eml() بارگذاری کنید، سپس هم save() و هم save_to_eml() را بر روی همان شیء mapi_message در حافظه فراخوانی کنید.

آیا load_from_eml() ایمن نسبت به چندنخی است؟

هر فراخوانی یک نمونه مستقل از mapi_message ایجاد می‌کند. چندین رشته می‌توانند همزمان load_from_eml() را صدا بزنند به شرطی که هر رشته از شیء خروجی خود استفاده کند.

چه اتفاقی برای پیام‌هایی که بدنه متن ساده ندارند می‌افتد؟

اگر EML فقط شامل بخش text/html باشد، message.body() یک رشته خالی برمی‌گرداند و message.html_body() محتوای HTML را حمل می‌کند. هر دو در طول سریال‌سازی MSG حفظ می‌شوند.


API Reference خلاصه

کلاس / متدتوضیح
mapi_message::load_from_eml(path)یک فایل EML را به mapi_message تجزیه کنید
mapi_message::load_from_eml(stream)EML را از یک std::istream تجزیه کنید
mapi_message::save(path)mapi_message را به یک فایل MSG سریال‌سازی کنید
mapi_message::save(stream)بایت‌های MSG را به یک std::ostream بنویسید
mapi_message::save()MSG را به عنوان std::vector<std::uint8_t> برگردانید
mapi_message::from_file(path)یک فایل MSG را در mapi_message بارگذاری کنید
mapi_message::from_stream(stream)بارگیری MSG از یک std::istream
mapi_message::save_to_eml(path)نوشتن EML به مسیر فایل
mapi_message::save_to_eml(stream)نوشتن بایت‌های EML به یک std::ostream
mapi_message::save_to_eml()بازگرداندن EML به عنوان std::vector<std::uint8_t>

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

 فارسی