Odczytywanie plików MSG
Odczytywanie plików MSG
mapi_message jest punktem wejścia do ładowania i parsowania plików Outlook MSG. Jedno wywołanie from_file() lub from_stream() odczytuje cały kontener CFB, wyodrębnia wszystkie właściwości MAPI i udostępnia je poprzez typowane metody dostępowe — nie wymaga instalacji Outlooka.
Ładowanie z ścieżki pliku
Użyj mapi_message::from_file() z 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';
}Ładowanie ze strumienia
Użyj mapi_message::from_stream(), gdy dane MSG pochodzą z gniazda sieciowego, archiwum lub dowolnego 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';
}Zawsze otwieraj strumień przy użyciu std::ios::binary. Strumienie w trybie tekstowym tłumaczą zakończenia linii w systemie Windows i uszkadzają kontener CFB.
Uzyskaj dostęp do właściwości wiadomości
mapi_message udostępnia najczęstsze właściwości wiadomości jako nazwane gettery:
#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";
}Iteruj odbiorców
message.recipients() zwraca std::vector obiektów odbiorców z display_name, email_address i 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';
}
}Iteruj załączniki
message.attachments() zwraca std::vector obiektów załączników. Każdy udostępnia filename, mime_type, data, content_id i 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()));
}
}
}Uzyskaj dostęp do osadzonych wiadomości
Gdy is_embedded_message() jest true, załącznik zawiera inny plik MSG. Uzyskaj do niego dostęp za pomocą 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"));
}
}
}Wskazówki i najlepsze praktyki
- Zawsze przekaż
std::ios::binarydostd::ifstreampodczas ładowania plików MSG. - Sprawdź
html_body()przedbody()— HTML-only messages przechowują swoją treść w właściwości HTML body i pozostawiająbody()pustą. from_file()ładuje wszystkie dane załączników do pamięci. Dla dużych plików MSG rozważ otwarcie podstawowego kontenera za pomocąmsg_reader, aby sprawdzić metadane bez pełnego materializowania bajtów załączników.- Parametr
strictwfrom_file(path, strict)ifrom_stream(stream, strict)domyślnie wynosifalse, tolerując drobne odchylenia strukturalne w rzeczywistych plikach MSG. - Obiekty odbiorcy udostępniają
recipient_type, aby odróżnić wpisy To, Cc i Bcc.
Typowe problemy
| Problem | Przyczyna | Naprawa |
|---|---|---|
msg_exception na pliku wyglądającym na prawidłowy | Plik nie jest prawdziwym kontenerem OLE CFB | Sprawdź przy użyciu cfb_reader::from_file() — jeśli również zgłosi błąd, plik nie jest prawidłowym MSG |
body() zwraca pusty ciąg | Wiadomość używa wyłącznie treści HTML | Użyj html_body() zamiast |
recipients() jest pusty | Starszy MSG bez tabeli odbiorców | Uzyskaj dostęp do display_to przez get_property_value() przy użyciu common_message_property_id::display_to |
| Uszkodzenie strumienia w systemie Windows | Strumień otwarty bez std::ios::binary | Dodaj flagę std::ios::binary do std::ifstream |
| Wysokie zużycie pamięci przy dużych plikach | Wszystkie dane załączników są ładowane wstępnie | Użyj msg_reader do niskopoziomowego dostępu bez pełnej materializacji |
FAQ
Czy from_file() utrzymuje otwarty uchwyt pliku?
Nie. Plik jest otwierany, w pełni analizowany i zamykany przed zwróceniem z metody. Możesz przenieść lub usunąć plik źródłowy po wywołaniu.
Jak sprawdzić, czy załącznik jest plikiem, czy osadzonym MSG?
Wywołaj attachment.is_embedded_message(). Zwraca true dla osadzonych plików MSG; false dla zwykłych załączników plikowych. Dla osadzonych wiadomości uzyskaj dostęp do zagnieżdżonego obiektu za pomocą attachment.embedded_message.
Jaka jest różnica między from_file() a używaniem msg_reader?
mapi_message::from_file() jest wysokopoziomowym API — analizuje pełną wiadomość i udostępnia właściwości jako pola typowane. msg_reader jest niskopoziomowym czytnikiem, który daje dostęp do surowej struktury kontenera CFB i jest przydatny, gdy trzeba zbadać układ wiadomości bez parsowania wszystkich właściwości MAPI.
Czy obsługiwane są zarówno pliki MSG w formacie Unicode, jak i ANSI?
Tak. mapi_message obsługuje zarówno Unicode (typ właściwości ptyp_string), jak i ANSI (ptyp_string8) string properties. unicode_strings() zwraca true dla wiadomości przechowywanych z właściwościami Unicode.
API Reference Podsumowanie
| Klasa / Metoda | Opis |
|---|---|
mapi_message::from_file(path) | Wczytaj plik MSG z std::filesystem::path |
mapi_message::from_file(path, strict) | Załaduj z opcją trybu ścisłego |
mapi_message::from_stream(stream) | Załaduj MSG z std::istream |
mapi_message::from_stream(stream, strict) | Załaduj ze strumienia z opcją trybu ścisłego |
mapi_message::subject() | Zwróć ciąg tematu wiadomości |
mapi_message::body() | Zwróć treść w formacie zwykłego tekstu |
mapi_message::html_body() | Zwróć treść HTML (pusta, jeśli nieobecna) |
mapi_message::sender_name() | Zwróć wyświetlaną nazwę nadawcy |
mapi_message::sender_email_address() | Zwróć adres e-mail nadawcy |
mapi_message::internet_message_id() | Zwróć nagłówek RFC 2822 Message-ID |
mapi_message::message_class() | Zwróć ciąg klasy wiadomości MAPI |
mapi_message::recipients() | Zwróć listę odbiorców |
mapi_message::attachments() | Zwróć listę załączników |
mapi_attachment::is_embedded_message() | True, jeśli załącznik jest osadzonym MSG |
mapi_message::unicode_strings() | True, jeśli wiadomość używa właściwości ciągów Unicode |