Создание и управление PST‑файлами

Помимо разбора существующего файла PST, Aspose.Email предоставляет возможности создания файла PST с нуля. Эта статья демонстрирует, как создавать файлы Outlook PST и добавлять в них подпапки или сообщения.

Создание файлов PST

Чтобы создать новый файл PST на локальном диске, необходимо использовать PersonalStorage class. С помощью этого класса вы можете создавать, читать и изменять файлы PST в ваших .NET приложениях. Создайте файл хранилища с нуля одной строкой кода:

// Create new PST
using var pst = PersonalStorage.Create(path, FileFormatVersion.Unicode);

Добавление подпапок в PST

Добавьте подпапку в корень PST‑файла, получив доступ к корневой папке и затем вызвав AddSubFolder метод.

В следующем фрагменте кода показано, как добавить подпапку под названием Inbox:

// Add new folder "Test"
pst.RootFolder.AddSubFolder("Inbox");

Проверка класса контейнера папки

При создании новых папок или добавлении элементов в существующие папки важно убедиться, что класс контейнера нового элемента или папки соответствует классу контейнера родительской папки, чтобы поддерживать организационную иерархию в файле хранилища PST. Для этой цели Aspose.Email имеет EnforceContainerClassMatching свойство FolderCreationOptions class. Свойство указывает, следует ли принудительно проверять класс контейнера добавляемой папки относительно класса контейнера родительской папки. Если установить значение ’true’, будет выброшено исключение, если классы контейнеров не совпадают. По умолчанию ‘false’.

Ниже приведён пример кода, демонстрирующий использование EnforceContainerClassMatching свойство для контроля того, должно ли быть выброшено исключение при добавлении папок с несовпадающими классами контейнеров:

using (var pst = PersonalStorage.Create("storage.pst", FileFormatVersion.Unicode))
{
    // Create a standard Contacts folder with the IPF.Contacts container class.
    var contacts = pst.CreatePredefinedFolder("Contacts", StandardIpmFolder.Contacts);
    
    // An exception will not arise. EnforceContainerClassMatching is false by default.
    contacts.AddSubFolder("Subfolder1", "IPF.Note");
    
    // An exception will occur as the container class of the subfolder being added (IPF.Note) 
    // does not match the container class of the parent folder (IPF.Contact).
    contacts.AddSubFolder("Subfolder3", new FolderCreationOptions {EnforceContainerClassMatching = true, ContainerClass = "IPF.Note"});
}

Примечание: Обеспечьте правильную обработку исключений при принудительном сопоставлении классов контейнеров, чтобы предотвратить непредвиденное поведение во время создания папок в PST.

Изменение класса контейнера папки

Иногда необходимо изменить класс контейнера папки. Частый пример — когда сообщения разных типов (встречи, письма и т.д.) добавляются в одну папку. В таких случаях класс папки нужно изменить для всех элементов, чтобы они правильно отображались. Ниже показан фрагмент кода, демонстрирующий, как изменить класс контейнера папки в PST для этой цели.

using var pst = PersonalStorage.FromFile("PersonalStorage1.pst);
var folder = pst.RootFolder.GetSubFolder("Inbox");

folder.ChangeContainerClass("IPF.Note");

Добавление файлов в PST

Ключевая функциональность Microsoft Outlook — управление письмами, календарями, задачами, контактами и записями журнала. Кроме того, файлы также могут быть добавлены в папку PST, и полученный PST сохраняет запись добавленных документов. Aspose.Email предоставляет возможность добавлять файлы в папку так же, как и сообщения, контакты, задачи и записи журнала в PST. Ниже приведён фрагмент кода, показывающий, как добавить документы в папку PST с помощью Aspose.Email.

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
using (var personalStorage = PersonalStorage.Create(dataDir + "Ps1_out.pst", FileFormatVersion.Unicode))
{
    var folder = personalStorage.RootFolder.AddSubFolder("Files");

    // Add Document.doc file with the "IPM.Document" message class by default.
    folder.AddFile(dataDir + "attachment_1.doc", null);
}

Добавление сообщений в файлы PST

С помощью Aspose.Email вы можете добавлять сообщения в подпапки PST‑файла, который вы создали или загрузили. Эта статья добавляет два сообщения с диска в подпапку Inbox PST‑файла. Используйте PersonalStorage и FolderInfo классы для добавления сообщений в файлы PST. Чтобы добавить сообщения в папку Inbox файла PST:

  1. Создайте экземпляр класса FolderInfo и загрузите в него содержимое папки Inbox.
  2. Добавьте сообщения с диска в папку Inbox, вызвав FolderInfo.AddMessage() метод. FolderInfo класс раскрывает AddMessages метод, позволяющий добавить большое количество сообщений в папку, сокращая операции ввода‑вывода на диск и повышая производительность.

Ниже показан фрагмент кода, демонстрирующий, как добавить сообщения в подпапку PST под названием Inbox.

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
// Create new PST            
var personalStorage = PersonalStorage.Create(dataDir, FileFormatVersion.Unicode);

// Add new folder "Inbox"
personalStorage.RootFolder.AddSubFolder("Inbox");

// Select the "Inbox" folder
var inboxFolder = personalStorage.RootFolder.GetSubFolder("Inbox");

// Add some messages to "Inbox" folder
inboxFolder.AddMessage(MapiMessage.FromFile(RunExamples.GetDataDir_Outlook() + "MapiMsgWithPoll.msg"));

Пакетное добавление сообщений с повышенной производительностью

Добавление отдельных сообщений в PST подразумевает больше операций ввода‑вывода на диск и может замедлять работу. Для повышения производительности сообщения можно добавлять в PST пакетным способом, минимизируя операции ввода‑вывода. AddMessages метод позволяет добавлять сообщения пакетно и может использоваться в следующих сценариях. Кроме того, MessageAdded событие происходит, когда сообщение добавлено в папку.

Добавить сообщения из другого PST

Чтобы добавить сообщения из другого PST, используйте FolderInfo.EnumerateMapiMessages метод, который возвращает IEnumerable<MapiMessage>:

using var srcPst = PersonalStorage.FromFile(@"source.pst", false);
using var destPst = PersonalStorage.FromFile(@"destination.pst");

// Get the folder by name
var srcFolder = srcPst.RootFolder.GetSubFolder("SomeFolder");
var destFolder = destPst.RootFolder.GetSubFolder("SomeFolder");

destFolder.MessageAdded += new MessageAddedEventHandler(OnMessageAdded);
destFolder.AddMessages(srcFolder.EnumerateMapiMessages());


// Handles the MessageAdded event.
static void OnMessageAdded(object sender, MessageAddedEventArgs e)
{
    Console.WriteLine($"Added: {e.EntryId}");
}

Добавить сообщения из каталога

Чтобы добавить сообщения из каталога, создайте GetMessages(string pathToDir) именованный метод‑итератор, который возвращает IEnumerable<MapiMessage>:

using var pst = PersonalStorage.FromFile(@"storage.pst");
var folder = pst.RootFolder.GetSubFolder("SomeFolder");
folder.MessageAdded += OnMessageAdded;
folder.AddMessages(GetMessages(@"MessageDirectory"));

// Named iterator method to read messages from directory.
static IEnumerable<MapiMessage> GetMessages(string pathToDir)
{
    string[] files = Directory.GetFiles(pathToDir, "*.msg");

    foreach (var file in files)
    {
        yield return MapiMessage.Load(file);
    }
}

// Handles the MessageAdded event.
static void OnMessageAdded(object sender, MessageAddedEventArgs e)
{
    Console.WriteLine($"Added: {e.EntryId}");
}

Загрузка сообщений с диска

Ниже показан фрагмент кода, демонстрирующий, как загрузить сообщения с диска.

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
private static void AddMessagesInBulkMode(string fileName, string msgFolderName)
{
    using (PersonalStorage personalStorage = PersonalStorage.FromFile(fileName))
    {
        FolderInfo folder = personalStorage.RootFolder.GetSubFolder("myInbox");
        folder.MessageAdded += OnMessageAdded;
        folder.AddMessages(new MapiMessageCollection(msgFolderName));
    }
}
static void OnMessageAdded(object sender, MessageAddedEventArgs e)
{
    Console.WriteLine(e.EntryId);
    Console.WriteLine(e.Message.Subject);
}

Реализация IEnumerable

Ниже показан фрагмент кода, демонстрирующий применение реализации IEnumerable.

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
public class MapiMessageCollection : IEnumerable<MapiMessage>
{
    private string path;

    public MapiMessageCollection(string path)
    {
        this.path = path;
    }

    public IEnumerator<MapiMessage> GetEnumerator()
    {
        return new MapiMessageEnumerator(path);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

public class MapiMessageEnumerator : IEnumerator<MapiMessage>
{
    private readonly string[] files;

    private int position = -1;

    public MapiMessageEnumerator(string path)
    {
        string path1 = RunExamples.GetDataDir_Outlook();
        files = Directory.GetFiles(path1);
    }

    public bool MoveNext()
    {
        position++;
        return (position < files.Length);
    }

    public void Reset()
    {
        position = -1;
    }

    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }

    public MapiMessage Current
    {
        get
        {
            try
            {
                return MapiMessage.FromFile(files[position]);
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
    public void Dispose()
    {
    }
}