Aspose.email.cpp 获取PST文件中邮件的附件数据,可以分块读取吗

System::SharedPtr<MapiAttachment> attachment = attachments->idx_get(attachmentIndex);
if(attachment)
{
	System::SharedPtr<System::IO::MemoryStream> stream = attachment->ToMemoryStream();
}

stream把整个附件的数据都读到内存了,大文件的话需要分块读取,有没有设置读取内容大小的方法?

@Yu_Zhou

Cause

The ToMemoryStream() method currently reads the entire attachment into memory, which can be inefficient for large files. Unfortunately, Aspose.Email for C++ does not provide a built-in method to read attachments in chunks directly.

Solution

To efficiently handle large attachments without loading them entirely into memory, you can manually read the attachment in smaller parts. This involves saving the attachment to a stream in manageable sizes. You can use the ExtractAttachments method to retrieve the attachment and then save it to a file or stream in chunks.

Code

Here’s a basic example of how to implement chunked reading of an attachment:

// Load the PST file
System::SharedPtr<PersonalStorage> pst = PersonalStorage::FromFile("path_to_your_pst_file.pst");

// Get the message containing the attachment
System::SharedPtr<MessageInfo> messageInfo = pst->ExtractMessage(entryId);

// Extract the attachments
System::SharedPtr<MapiAttachmentCollection> attachments = pst->ExtractAttachments(messageInfo);

// Loop through each attachment
for (int i = 0; i < attachments->get_Count(); i++)
{
    System::SharedPtr<MapiAttachment> attachment = attachments->idx_get(i);
    if (attachment)
    {
        // Open a file stream to save the attachment
        System::SharedPtr<System::IO::FileStream> fileStream = System::IO::File::OpenWrite("path_to_save\\" + attachment->get_LongFileName());

        // Read the attachment in chunks
        const int chunkSize = 1024 * 1024; // 1 MB chunks
        int bytesRead;
        uint8_t buffer[chunkSize];

        // Use a MemoryStream to read the attachment in chunks
        System::SharedPtr<System::IO::MemoryStream> memoryStream = attachment->ToMemoryStream();
        while ((bytesRead = memoryStream->Read(buffer, 0, chunkSize)) > 0)
        {
            fileStream->Write(buffer, 0, bytesRead);
        }

        fileStream->Close();
    }
}

Next Steps

  1. Adjust the chunkSize variable based on your memory constraints and performance needs.
  2. Test the implementation with various attachment sizes to ensure it works as expected.
  3. Implement error handling to manage any issues during file reading or writing.

Please let me know if you need further assistance!

想问一下,后续有计划会支持分块读取附件的能力吗?目前有一些开源库是支持该能力的(例如libpff)

m_spPst = Aspose::Email::Storage::Pst::PersonalStorage::FromFile(filePath, false);
auto msg = m_spPst->ExtractMessage(entryId);
if (msg)
    int num = msg.get_shared_count();

System::SharedPtr< Aspose::email::Mapi::MapiMessage > ExtractMessage (System::String entryId)
这个函数返回的智能指针对象,为什么引用计数是3,导致其内存不会被释放