EML と MSG の変換
EML と MSG の変換
Aspose.Email FOSS for 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() で読み込み、次に save() で MSG にシリアライズします:
#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 の件名、プレーンテキスト本文、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";
}ストリームベースの変換
4つの該当メソッドはすべて、ファイルシステムに触れずにパイプライン方式の処理を行うための 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)を優先してください;パスのオーバーロードはファイルのオープンを内部で処理し、ややシンプルです。 - サービス間でデータをパイプするときは、一時ファイルを避けるためにバイトのオーバーロード(引数なしの
save()とsave_to_eml())を使用してください。 - 件名、本文、HTML 本文、送信者、受信者、そして MIME 添付ファイルはすべて、往復全体で保持されます。
- IMAP フラグ、ルーティングヘッダー、そして TNEF エンコードされたコンテンツは変換時に引き継がれません。
一般的な問題
| 問題 | 原因 | 修正 |
|---|---|---|
load_from_eml が有効なファイルで例外を投げる | EML の非 CRLF 改行 | EML が RFC 5322 の CRLF を使用していることを確認してください;一部のエクスポートツールは LF のみを書き込みます |
| EML → MSG 変換後に添付ファイルが欠落 | 標準外の MIME 添付エンコーディング | EML が multipart/mixed を標準の Content-Disposition: attachment と共に使用していることを確認する |
| MSG の後に空の HTML 本文 → EML | ソース MSG はプレーンテキスト本文のみです | message.html_body() を確認してください;空の場合、プレーンテキストのみが保存されました |
| ストリーム出力が破損しています | ストリームがテキストモードで開かれています | 常に std::ios::binary を使用してください |
件名に ?= シーケンスが表示されます | 元の EML に RFC 2047 エンコード語が含まれています | RFC 2047 ライブラリでデコードします;ライブラリはエンコードされた形式を保持します |
FAQ
EML → MSG は HTML 本文を保持しますか?
はい。text/html MIME パートは MAPI HTML 本文プロパティに保存され、読み込み後は message.html_body() でアクセスできます。
添付ファイルは両方向で保持されますか?
はい。すべての MIME 添付パートは mapi_message 添付リストを通じて引き継がれます。バイナリ添付データは attachment.data(std::vector<std::uint8_t>)として利用可能です。
単一の EML を同時に複数の出力形式に変換できますか?
はい。load_from_eml() で EML を一度読み込み、同じインメモリ mapi_message オブジェクトに対して save() と save_to_eml() の両方を呼び出します。
load_from_eml() はスレッドセーフですか?
各呼び出しは独立した mapi_message インスタンスを作成します。各スレッドが独自の出力オブジェクトを使用している限り、複数のスレッドが同時に load_from_eml() を呼び出すことができます。
プレーンテキスト本文がないメッセージはどうなりますか?
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) | std::istream から EML をパースします |
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> として返す |