Comment travailler avec des pièces jointes en C++

Comment travailler avec des pièces jointes en C++

Aspose.Email FOSS for C++ provides the mapi_attachment Classe pour créer des attachements de l’électricité ou des flux, et le mapi_message Liste d’attaches pour la lecture des annexes de fichiers existants. Vous pouvez ajouter des pièces jointes lors de la composition des messages et les inspecter lors du chargement de fichiers, y compris la détection si une pièce jointe est elle-même un fichier intégré Message de la place.

Étape 1 - Définir le projet

git clone https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-Cpp.git
add_subdirectory(Aspose.Email-FOSS-for-Cpp)
target_link_libraries(your_target PRIVATE AsposeEmailFoss::AsposeEmailFoss)

Étape 2 – Ajouter un fichier joint à partir de bytes

Utilisez mapi_message::add_attachment() - Ajout de données binaires lors de la composition d’un message. Fournir le nom de fichier, les octets bruts comme a std::vector<std::uint8_t>,et le lieu de la Type de contenu :

#include <filesystem>
#include <vector>
#include "aspose/email/foss/msg/mapi_message.hpp"

int main()
{
    auto message = aspose::email::foss::msg::mapi_message::create(
        "Report", "Please review the attached report.");
    message.set_sender_name("Alice");
    message.set_sender_email_address("alice@example.com");
    message.add_recipient("bob@example.com", "Bob");

    // Attach a text file
    std::vector<std::uint8_t> text_data{'H', 'e', 'l', 'l', 'o'};
    message.add_attachment("notes.txt", text_data, "text/plain");

    // Attach a binary blob
    std::vector<std::uint8_t> bin_data{0x00, 0x01, 0x02, 0x03};
    message.add_attachment("data.bin", bin_data, "application/octet-stream");

    message.save(std::filesystem::path("report.msg"));
}

Étape 3 – Ajouter une pièce jointe à un fichier sur le disque

Lire le fichier dans un vecteur de byte, puis le passer à add_attachment():

#include <filesystem>
#include <fstream>
#include <iterator>
#include <vector>
#include "aspose/email/foss/msg/mapi_message.hpp"

int main()
{
    // Read a file into bytes
    std::ifstream file("document.pdf", std::ios::binary);
    std::vector<std::uint8_t> pdf_bytes(
        std::istreambuf_iterator<char>(file),
        std::istreambuf_iterator<char>{});

    auto message = aspose::email::foss::msg::mapi_message::create(
        "Document", "See attached PDF.");
    message.set_sender_name("Alice");
    message.set_sender_email_address("alice@example.com");
    message.add_recipient("bob@example.com", "Bob");
    message.add_attachment("document.pdf", pdf_bytes, "application/pdf");

    message.save(std::filesystem::path("with_pdf.msg"));
}

Étape 4 — Lire les pièces jointes d’un fichier MSG existant

message.attachments() Retour à const référence à un vecteur d’objets attachés. Chaque exposition filename, mime_type, data (les barres de rouge) et content_id:

#include <fstream>
#include <iostream>
#include "aspose/email/foss/msg/mapi_message.hpp"

int main()
{
    std::ifstream input("sample.msg", std::ios::binary);
    const auto message = aspose::email::foss::msg::mapi_message::from_stream(input);

    std::cout << "Attachments: " << message.attachments().size() << '\n';
    for (std::size_t i = 0; i < message.attachments().size(); ++i)
    {
        const auto& a = message.attachments()[i];
        std::cout << "[" << (i + 1) << "]"
                  << "  name="         << a.filename
                  << "  mime="         << a.mime_type
                  << "  bytes="        << a.data.size()
                  << "  content_id="   << a.content_id
                  << '\n';
    }
}

Étape 5 – Détecter et accéder aux messages embarqués

Certains fichiers contiennent d’autres fiches comme pièces jointes (invitations à la réunion ou à l’envoi). Utilisez is_embedded_message() pour les détecter et accéder au message niché à travers embedded_message:

#include <fstream>
#include <iostream>
#include "aspose/email/foss/msg/mapi_message.hpp"

int main()
{
    std::ifstream input("sample.msg", std::ios::binary);
    const auto message = aspose::email::foss::msg::mapi_message::from_stream(input);

    for (const auto& attachment : message.attachments())
    {
        if (attachment.is_embedded_message() && attachment.embedded_message != nullptr)
        {
            const auto& inner = *attachment.embedded_message;
            std::cout << "Embedded subject: " << inner.subject() << '\n';
            std::cout << "Embedded from:    " << inner.sender_email_address() << '\n';

            // Save the embedded message as a standalone MSG
            inner.save(std::filesystem::path("embedded.msg"));
        }
        else
        {
            std::cout << "Regular attachment: " << attachment.filename
                      << " (" << attachment.data.size() << " bytes)\n";
        }
    }
}

Étape 6 – Enregistrer les données d’attachement sur le disque

Extractez des octets d’annexe et écrivez-les dans un fichier en utilisant les flux de fichiers C++ standard:

#include <filesystem>
#include <fstream>
#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"));

    const std::filesystem::path out_dir("attachments");
    std::filesystem::create_directories(out_dir);

    for (const auto& a : message.attachments())
    {
        if (!a.is_embedded_message())
        {
            const auto out_path = out_dir / a.filename;
            std::ofstream out(out_path, std::ios::binary);
            out.write(reinterpret_cast<const char*>(a.data.data()),
                      static_cast<std::streamsize>(a.data.size()));
            std::cout << "Saved: " << out_path << '\n';
        }
    }
}

Problèmes courants et solutions

attachment.data Il est vide pour un grand attachement connu. Vérifier la source du fichier MSG contient effectivement les données d’annexe (pas un lien OLE). MSG fichiers exportés à partir de certains Les clients de messagerie peuvent stocker les pièces jointes comme références externes que la bibliothèque ne peut pas suivre.

is_embedded_message() retournés true Mais embedded_message est nullptr. Le l’en-tête de l’annexe indique un MSG intégré, mais les données n’ont pas été lisibles. La source MSG est valide et non truncée.

Enregistrer l’attachement extrait échoue avec une erreur de chemin. Quelques fichiers d’attachement contiennent des caractères qui sont invalides sur le système de fichiers cible (par exemple,., :, ? est Votre santé ? - Sanitise attachment.filename avant de construire le parcours d’exploitation.

Les fichiers de grande taille MSG entraînent une utilisation élevée de la mémoire. - lemapi_message::from_file() Charges toutes pour les fichiers de grande taille, ouvrez le conteneur CFB sous-jacent avec un cfb_reader pour accéder à des flux individuels sans matérialiser complètement tous les pièces jointes.

add_attachment() Pas trouvé au moment de la compilation. Assurez-vous d’utiliser le bon comprend : "aspose/email/foss/msg/mapi_message.hpp".La méthode est un membre de aspose::email::foss::msg::mapi_message.

Questions fréquentes

Quels types de MIME dois-je utiliser pour les pièces jointes?

Utilisez le type standard IANA MIME pour le format de fichier : "text/plain" pour .txt, "application/pdf" pour .pdf, "application/octet-stream" Un retournement générique pour le type MIME est stocké comme le attach_mime_tag Propriété de la propriété.

Puis-je joindre le même fichier plusieurs fois ?

Oui, chaque appel à add_attachment() Une entrée indépendante est ajoutée. Dupliquer Les noms de fichiers sont autorisés ; ils sont distingués par leur position dans la liste des pièces jointes.

Comment définir l’ID de contenu pour les images en ligne ?

Passez la chaîne d’ID de contenu comme quatrième argument à mapi_attachment::from_stream():

auto att = aspose::email::foss::msg::mapi_attachment::from_bytes(
    "logo.png", png_bytes, "image/png", "<logo-cid@example.com>");

content_id Il est exposé comme attachment.content_id Quand je lis en arrière.

est attachment.data Une référence ou une copie ?

attachment.data est a std::vector<std::uint8_t> stocké par valeur à l’intérieur de la mapi_message L’accès à l’objet ne déclenche pas d’I/O supplémentaire.

Puis-je supprimer un pièce jointe avant d’enregistrer?

Le mapi_message L’API n’expose pas une méthode de suppression-attachement directe dans la version 0.1.0. Build a new message, copy the desired properties and attachments manually, Sauvegarder le nouvel objet.

Voir aussi

 Français