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로 변환
mapi_message::load_from_eml()으로 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로 변환
mapi_message::from_file()으로 MSG 파일을 로드한 다음, 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)를 선호하세요; 경로 오버로드는 파일 열기를 내부에서 처리하며 약간 더 간단합니다. - 서비스 간에 데이터를 파이핑할 때 임시 파일을 방지하려면 바이트 오버로드(
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 → EML 후 HTML 본문이 비어 있음 | 원본 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 (a 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>로 반환합니다 |