การแปลง 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(), จากนั้นทำการซีเรียลไลซ์เป็น MSG ด้วย save():

#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, เนื้อหาข้อความแบบ plain-text, เนื้อหา 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 เสมอ สตรีมแบบข้อความจะแปลงจบบรรทัดบน Windows ทำให้ข้อมูล CFB แบบไบนารีเสียหาย.


การแปลงในหน่วยความจำ (ไบต์)

save() และ save_to_eml() มีการโอเวอร์โหลดแบบไม่มีอาร์กิวเมนต์ที่ส่งคืน std::vector<std::uint8_t> ทั้งสอง ใช้เหล่านี้เพื่อหลีกเลี่ยงการ I/O ของระบบไฟล์ทั้งหมด:

#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 — ทั้งการอ่านและการเขียน.
  • ควรใช้ load_from_eml(path) แทน overload ของสตรีมเมื่อคุณมีเส้นทาง; overload ของเส้นทางจัดการการเปิดไฟล์ภายในและง่ายกว่าเล็กน้อย.
  • ใช้ overload แบบไบต์ (save() และ save_to_eml() โดยไม่มีอาร์กิวเมนต์) เมื่อทำการส่งข้อมูลระหว่างบริการเพื่อหลีกเลี่ยงไฟล์ชั่วคราว.
  • หัวเรื่อง, เนื้อหา, HTML body, ผู้ส่ง, ผู้รับ, และไฟล์แนบ MIME ทั้งหมดจะถูกคงไว้ตลอดการเดินทางรอบเต็ม.
  • แฟล็ก IMAP, ส่วนหัวการกำหนดเส้นทาง, และเนื้อหาที่เข้ารหัสด้วย TNEF จะไม่ถูกส่งต่อผ่านการแปลง.

ปัญหาทั่วไป

ปัญหาสาเหตุวิธีแก้
load_from_eml ทำให้เกิดข้อผิดพลาดบนไฟล์ที่ถูกต้องบรรทัดสิ้นสุดไม่ใช่ CRLF ในไฟล์ EMLตรวจสอบให้แน่ใจว่า EML ใช้ CRLF ตาม RFC 5322; เครื่องมือส่งออกบางตัวเขียนเป็น LF เพียว
ไฟล์แนบหายหลังจากแปลง EML → MSGการเข้ารหัสไฟล์แนบ MIME ที่ไม่เป็นมาตรฐานตรวจสอบว่า EML ใช้ multipart/mixed พร้อมกับ Content-Disposition: attachment มาตรฐาน
เนื้อหา HTML ว่างหลังจาก MSG → EMLMSG ต้นทางมีเพียงเนื้อความข้อความธรรมดาตรวจสอบ message.html_body(); หากว่าง จะมีการจัดเก็บเพียงข้อความธรรมดา
ข้อมูลสตรีมเสียหายสตรีมเปิดในโหมดข้อความใช้ std::ios::binary เสมอ
หัวเรื่องแสดงลำดับ ?=คำเข้ารหัส RFC 2047 ใน EML ดั้งเดิมถอดรหัสด้วยไลบรารี RFC 2047; ไลบรารีจะคงรูปแบบที่เข้ารหัสไว้

FAQ

EML → MSG รักษา HTML body หรือไม่?

ใช่ ส่วน MIME text/html จะถูกเก็บไว้ในคุณสมบัติ body ของ 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() พร้อมกันได้ ตราบใดที่แต่ละเธรดใช้วัตถุผลลัพธ์ของตนเอง.

เกิดอะไรขึ้นกับข้อความที่ไม่มีส่วนเนื้อหา plain-text?

หากไฟล์ 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>

ดูเพิ่มเติม

 ภาษาไทย