خواندن فایلهای 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 استفاده کند |