读取和转换 Outlook 文件
使用 OST 文件
Aspose.Email for .NET 提供了读取 Microsoft Outlook OST 文件的 API。您可以将 OST 文件从磁盘或流加载到一个实例中 Aspose.Email.Outlook.Pst.PersonalStorage 用于访问其内容的类,例如文件夹、子文件夹和邮件。当使用 POP3 或 IMAP 邮件服务器时,Microsoft Outlook 会创建 PST 文件来存储邮件。相反,当使用 Microsoft Exchange 作为邮件服务器时,会创建 OST 文件。OST 文件也支持比 PST 文件更大的文件大小。
读取 OST 文件
使用 Aspose.Email 读取 OST 文件的过程与读取 PST 文件完全相同。相同的代码可以读取 PST 和 OST 文件:只需向 PersonalStorage.FromFile() 方法。下面的代码片段演示了如何读取 OST 文件。
将 OST 转换为 PST
Try it out!
使用免费在线转换电子邮件和消息归档 Aspose.Email 转换应用.
欲进行其他 OST 文件操作,请参阅以下页面:
- 读取 PST 文件并检索信息
- 获取 Outlook PST 文件中的邮件信息
- 从 Outlook PST 文件提取邮件并以 MSG 格式保存到磁盘或流中
- 从 Outlook PST 文件访问联系人信息并以 MSG 格式保存到磁盘
将 PST 转换为 OST
Aspose.Email 不支持将 PST 转换为 OST,因为 OST 始终由 Outlook 在添加账户并与邮件服务器同步时创建。PST 与 OST 的区别在于 PST 仅在本地可用,而 OST 内容也在邮件服务器上可用。因此无需将 PST 转换为 OST 以供本地使用。但可以使用 Outlook 的导入/导出向导将 PST 导入现有账户。
OLM 是 Microsoft Outlook 用于存储本地数据(如电子邮件、附件、笔记、日历数据、联系人、任务、历史记录等)的专有文件格式。OLM 文件仅与 Outlook for Mac 兼容,无法在使用 PST 文件格式的 Windows 版 Outlook 中打开或访问。
使用 OLM 文件
打开 OLM 文件
OLM 格式文件可以通过两种方式打开:
- 使用构造函数
- 使用静态 FromFile 方法
这些方法在行为上存在差异。请参阅下文。
使用构造函数
要打开文件,请调用 OlmStorage 类并将完整文件名或流作为参数传入:
var fileName = "MyStorage.olm";
var olm = new OlmStorage(fileName);
使用静态方法 FromFile
要打开文件,请使用静态方法 FromFile 并将完整文件名或流作为参数传入:
var fileName = "MyStorage.olm";
var olm = OlmStorage.FromFile(fileName);
检索文件夹
要访问 OLM 文件的目录结构,请创建以下类的实例: OlmStorage 类,使用其构造函数并传入文件路径。文件打开后,使用以下方式访问其目录结构: FolderHierarchy 属性。该属性返回一个列表,包含 OlmFolder 对象,每个代表 OLM 文件中的一个目录。要进一步探索目录结构,请访问 SubFolders 每个对象的属性,返回其子目录的列表。通过使用这些属性,您可以遍历 OLM 文件的整个目录层次结构,访问其中包含的所有目录和子目录。
下面的示例按层级顺序显示所有文件夹的列表:
using (var olm = new OlmStorage(fileName))
{
PrintAllFolders(olm.FolderHierarchy, string.Empty);
}
private void PrintAllFolders(List<OlmFolder> folderHierarchy, string indent)
{
foreach (var folder in folderHierarchy)
{
Console.WriteLine($"{indent}{folder.Name}");
PrintAllFolders(folder.SubFolders, indent+"-");
}
}
使用 FromFile 方法打开 OLM 文件, FolderHierarchy 属性默认不会被初始化,返回 null。在这种情况下,需要显式调用 GetFolders 方法来初始化它。 FolderHierarchy 属性并检索 OLM 文件中的目录列表:
using (var olm = OlmStorage.FromFile(fileName))
{
var folders = olm.GetFolders();
}
另外,也可以通过名称获取任意文件夹:
- 调用 GetFolder 方法。
- 将文件夹名称作为第一个参数,第二个参数传入一个值,指示在搜索文件夹时是否忽略大小写。
using (var olm = OlmStorage.FromFile(fileName))
{
// get inbox folder by name
OlmFolder folder = olm.GetFolder("Inbox", true);
}
列出邮件
OlmFolder 类,表示文件夹,具有以下获取邮件列表的方法:
- EnumerateMessages 实现了文件夹中邮件的迭代。在这种情况下,每次迭代返回 OlmMessageInfo 对象,提供邮件的简要信息。
- EnumerateMapiMessages,也实现了文件夹中邮件的迭代,但在这种情况下,每次迭代返回 MapiMessage 对象,表示邮件本身,包含所有属性。
使用 EnumerateMessages 方法
using (var olm = OlmStorage.FromFile(fileName))
{
var folder = olm.GetFolder("Inbox", true);
foreach (var messageInfo in folder.EnumerateMessages())
{
Console.WriteLine(messageInfo.Subject);
}
}
使用 EnumerateMapiMessages 方法
using (var olm = OlmStorage.FromFile(fileName))
{
var folder = olm.GetFolder("Inbox", true);
foreach (var msg in folder.EnumerateMapiMessages())
{
// save message in MSG format
msg.Save($"{msg.Subject}.msg");
}
}
其他有用属性
OlmFolder 类的其他有用属性如下: HasMessages 和 MessageCount 属性,返回文件夹中是否存在邮件以及它们的数量。
using (var olm = OlmStorage.FromFile(fileName))
{
var folder = olm.GetFolder("Inbox", true);
if (folder.HasMessages)
{
Console.WriteLine($"Message count: {folder.MessageCount}");
}
}
获取或设置消息的修改日期
修改日期表示 OLM 邮件最后一次修改的日期和时间。您可以使用 OlmMessageInfo.ModifiedDate 用于检索或更新 OLM 邮件修改日期值的属性。
以下示例演示了该属性的用法:
foreach (OlmMessageInfo messageInfo in inboxFolder.EnumerateMessages())
{
DateTime modifiedDate = messageInfo.ModifiedDate;
}
提取电子邮件和项目
OlmStorage 类拥有 ExtractMapiMessage 允许提取电子邮件的方法。此方法接收一个 OlmMessageInfo 对象。
using (var olm = OlmStorage.FromFile(fileName))
{
var folder = olm.GetFolder("Inbox", true);
foreach (var messageInfo in folder.EnumerateMessages())
{
if (messageInfo.Date == DateTime.Today)
{
// Extracts today's messages form Inbox
var msg = olm.ExtractMapiMessage(messageInfo);
}
}
}
使用遍历 API
即使原始文件的部分数据已损坏,也可以尽可能提取 Outlook OLM 文件中的所有项目,而不会抛出异常。要实现此功能,请使用 OlmStorage(TraversalExceptionsCallback callback) 构造函数和 Load(string fileName) 使用该方法而不是 FromFile 方法。构造函数允许定义回调方法。
using (var olm = new OlmStorage((exception, id) => { /* Exception handling code. */ }))
回调方法会将加载和遍历过程中的异常暴露出来。
该 Load 如果文件成功加载且可以继续遍历,方法返回 ’true’。如果文件已损坏且无法遍历,则返回 ‘false’。
if (olm.Load(fileName))
以下代码片段和步骤展示了如何使用此 API:
- 创建该类的新实例 OlmStorage 类,传入异常处理回调以处理过程中的任何异常。
- 通过调用以下方法加载 OLM 文件: Load OlmStorage 实例的方法。
- 如果 OLM 文件成功加载,可通过调用以下方法获取文件夹层次结构: GetFolders 在 OlmStorage 实例上的方法。它返回 OlmFolder 对象的列表。
- 调用 ExtractItems 方法,传入 OlmStorage 实例和 OlmFolder 对象列表。
- 在 ExtractItems 方法中,遍历 folders 列表中的每个文件夹。
- 如果文件夹包含消息(电子邮件),使用 Console.WriteLine(folder) 将文件夹名称打印到控制台。
- 通过在 OlmStorage 实例上调用 EnumerateMessages 方法,并传入当前文件夹作为参数,遍历当前文件夹中的消息。
- 使用 Console.WriteLine(msg.Subject) 将每条消息的主题打印到控制台。
- 如果文件夹有子文件夹,递归调用 ExtractItems 方法,传入 OlmStorage 实例以及当前文件夹的子文件夹。
using (var olm = new OlmStorage((exception, id) => { /* Exception handling code. */ }))
{
if (olm.Load(fileName))
{
var folderHierarchy = olm.GetFolders();
ExtractItems(olm, folderHierarchy);
}
}
private static void ExtractItems(OlmStorage olm, List<OlmFolder> folders)
{
foreach (var folder in folders)
{
if (folder.HasMessages)
{
Console.WriteLine(folder);
foreach (var msg in olm.EnumerateMessages(folder))
{
Console.WriteLine(msg.Subject);
}
}
if (folder.SubFolders.Count > 0)
{
ExtractItems(olm, folder.SubFolders);
}
}
}
按标识符提取邮件
有时需要按标识符提取特定邮件。例如,您的应用程序将标识符存储在数据库中,并按需提取邮件。这是一种高效的方式,可避免每次遍历整个存储以查找要提取的特定邮件。此功能适用于 OLM 存储。该 EntryId 属性的 OlmMessageInfo 类获取邮件条目标识符。重载的 ExtractMapiMessage(string id) 方法的 OlmStorage 类从 OLM 获取邮件。
下面的代码展示了如何按标识符从 OLM 提取邮件。
代码执行以下步骤:
- 启动 foreach 循环遍历列表中的 OlmMessageInfo 对象。循环使用 EnumerateMessages olmFolder 对象的方法,以检索当前遍历的文件夹中的所有邮件列表。
- 循环通过调用 ExtractMapiMessage(string id) 方法的 OlmStorage 类,传入 EntryId 作为参数传递当前邮件的
检索到的 MapiMessage 对象可用于访问和操作邮件内容。循环将持续,直至文件夹中的所有邮件都被处理完毕。
foreach (OlmMessageInfo msgInfo in olmFolder.EnumerateMessages())
{
MapiMessage msg = storage.ExtractMapiMessage(msgInfo.EntryId);
}
获取文件夹路径
您也可以获取 OML 文件中各文件夹的路径。Aspose.Email 提供了 OlmFolder.Path 返回文件夹路径的属性。以下代码片段演示了其用法 OlmFolder.Path 用于获取 OML 文件中文件夹路径的属性。
var storage = new OlmStorage("SampleOLM.olm");
PrintPath(storage, storage.FolderHierarchy);
public static void PrintPath(OlmStorage storage, List<OlmFolder> folders)
{
foreach (OlmFolder folder in folders)
{
// print the current folder path
Console.WriteLine(folder.Path);
if (folder.SubFolders.Count > 0)
{
PrintPath(storage, folder.SubFolders);
}
}
}
统计文件夹中的项目数
您也可以统计文件夹中项目的数量。Aspose.Email 提供了 OlmFolder.MessageCount 返回文件夹中项目数量的属性。以下代码片段演示了其用法 OlmFolder.MessageCount 用于获取 OML 文件中文件夹项目数量的属性。
var storage = new OlmStorage("SampleOLM.olm");
PrintMessageCount(storage.FolderHierarchy);
public static void PrintMessageCount(List<OlmFolder> folders)
{
foreach (OlmFolder folder in folders)
{
Console.WriteLine("Message Count [" + folder.Name + "]: " + folder.MessageCount);
}
}
获取 OlmStorage 的总项目计数
OlmStorage 类还具有 GetTotalItemsCount() 返回 OLM 存储中邮件项目总数的方法。
using (var olm = new OlmStorage("storage.olm"))
{
var count = olm.GetTotalItemsCount();
}
Outlook 类别颜色检索
要处理存储在 OLM 文件中的类别颜色或 Outlook 项目类别,Aspose.Email 提供以下解决方案:
- OlmItemCategory 类 - 表示 Outlook 项目的类别,可通过名称及其十六进制表示的关联颜色获取。
- GetCategories() 方法的 OlmStorage 类 - 检索类别列表。
以下代码示例演示了如何从 OML 存储中获取所有已使用的类别:
using (var olm = OlmStorage.FromFile("storage.olm"))
{
var categories = olm.GetCategories();
foreach (var category in categories)
{
Console.WriteLine($"Category name: {category.Name}");
//Color is represented as a hexadecimal value: #rrggbb
Console.WriteLine($"Category color: {category.Color}");
}
}
下面的代码示例展示了如何获取邮件类别颜色:
foreach (var msg in olm.EnumerateMessages(folder))
{
if (msg.Categories != null)
{
foreach (var msgCategory in msg.Categories)
{
Console.WriteLine($"Category name: {msgCategory}");
var categoryColor = cat.First(c => c.Name.Equals(msgCategory, StringComparison.OrdinalIgnoreCase)).Color;
Console.WriteLine($"Category color: {categoryColor}");
}
}
}
将 OLM 转换为 PST
OLM 是一种由 Microsoft Outlook for Mac 系统使用的数据库文件格式。OLM 文件存储电子邮件、日历数据、联系人数据以及应用设置。Windows 版 Outlook 不支持 OLM 文件。因此,无法在 Windows 版 Outlook 中打开 Mac 版 Outlook(OLM)文件。如果您想将邮箱从 Mac 版 Outlook 迁移到 Windows 版 Outlook,需要将 Mac 版 Outlook 的 OLM 文件转换为 Outlook PST 文件格式。
代码步骤
要将 OLM 文件转换为 PST,请按照以下步骤操作:
- 创建以下实例: OlmStorage 用于打开源 OLM 的类。
- 打开源 OLM 文件。
- 使用以下方式创建新 PST 文件 Create 方法。
- 创建一个 GetContainerClass 方法,将邮件类映射到文件夹类。
- 创建一个 AddToPst 方法,使用 EnumerateMapiMessages 方法递归读取 OLM 中的每个文件夹及其邮件,并使用 AddSubFolder 和 AddMessage 方法按相同顺序将它们添加到 PST 中。
代码示例
以下代码示例展示了如何将 OLM 转换为 PST。
Main 方法:
// create an instance of OlmStorage class to open source OLM
using (var olm = new OlmStorage("my.olm"))
// create a new PST file
using (var pst = PersonalStorage.Create("my.pst", FileFormatVersion.Unicode))
{
// recursively reads each folder and its messages
// and adds them to the PST in the same order
foreach (var olmFolder in olm.FolderHierarchy)
{
AddToPst(pst.RootFolder, olmFolder);
}
}
GetContainerClass 方法实现:
public string GetContainerClass(string messageClass)
{
if (messageClass.StartsWith("IPM.Contact") || messageClass.StartsWith("IPM.DistList"))
{
return "IPF.Contact";
}
if (messageClass.StartsWith("IPM.StickyNote"))
{
return "IPF.StickyNote";
}
if (messageClass.StartsWith("IPM.Activity"))
{
return "IPF.Journal";
}
if (messageClass.StartsWith("IPM.Task"))
{
return "IPF.Task";
}
if (messageClass.StartsWith("IPM.Appointment") || messageClass.StartsWith("IPM.Schedule.meeting"))
{
return "IPF.Appointment";
}
return "IPF.Note";
}
AddToPst 方法实现:
public void AddToPst(FolderInfo pstFolder, OlmFolder olmFolder)
{
FolderInfo pstSubFolder = pstFolder.GetSubFolder(olmFolder.Name);
foreach (var msg in olmFolder.EnumerateMapiMessages())
{
if (pstSubFolder == null)
{
pstSubFolder = pstFolder.AddSubFolder(olmFolder.Name, GetContainerClass(msg.MessageClass));
}
pstSubFolder.AddMessage(msg);
}
if (pstSubFolder == null)
{
pstSubFolder = pstFolder.AddSubFolder(olmFolder.Name);
}
foreach (var olmSubFolder in olmFolder.SubFolders)
{
AddToPst(pstSubFolder, olmSubFolder);
}
}