การแปลง EML และ MSG
การแปลง EML และ MSG
Aspose.Email FOSS สำหรับ C++ แปลงแบบสองทางระหว่าง EML (RFC 5322 / MIME) และ MSG (Outlook MAPI) รูปแบบโดยใช้ mapi_message. เส้นทางการแปลงคือ: load_from_eml() → ในหน่วยความจำ mapi_message → save() สำหรับ 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 → EML | MSG ต้นทางมีเพียงเนื้อความข้อความธรรมดา | ตรวจสอบ 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> |