การอ่านไฟล์ 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 |