Flux et pièces jointes de fichiers
Flux et pièces jointes de fichiers
Au-delà des surcharges de base Document.Open/Document.Save, Aspose.PDF FOSS pour .NET vous offre un contrôle plus fin sur la façon dont les octets circulent dans et hors d’un document — des tampons en mémoire extensibles pour des fichiers très volumineux, et un API dédié pour intégrer, inspecter et extraire les pièces jointes de fichiers via FileSpecification et EmbeddedFileCollection.
Extension des tampons en mémoire au-delà de 2Go
MemoryStream stocke ses données dans un tableau contigu unique, ce qui limite la taille à environ 2Go. OptimizedMemoryStream stocke les données en blocs de taille fixe à la place, ce qui lui permet de contenir des documents bien plus grands lorsque vous enregistrez ou construisez un PDF entièrement en mémoire.
using Aspose.Pdf;
using var doc = Document.Open("large-input.pdf");
using var buffer = new OptimizedMemoryStream();
doc.Save(buffer);
buffer.Seek(0, SeekOrigin.Begin);
byte[] allBytes = buffer.ToArray();
Console.WriteLine($"Buffer length: {buffer.Length}");Vous pouvez également y écrire directement, de la même façon que vous le feriez avec n’importe quel Stream:
using var buffer = new OptimizedMemoryStream();
byte[] chunk = System.Text.Encoding.UTF8.GetBytes("raw content chunk");
buffer.Write(chunk, 0, chunk.Length);
buffer.WriteByte(0x0A);
buffer.SetLength(buffer.Length);Intégration d’un fichier directement depuis un flux
FileSpecification peut envelopper un Stream au lieu de vous obliger à mettre en mémoire tampon la pièce jointe dans un byte[] au préalable. Cela est utile lorsque la source de la pièce jointe est elle-même un flux, comme par exemple un descripteur de fichier ouvert.
using Aspose.Pdf;
using var doc = Document.Open("input.pdf");
using var attachmentStream = File.OpenRead("report.csv");
using var spec = new FileSpecification(attachmentStream, "report.csv", "Quarterly report data");
spec.MimeType = "text/csv";
spec.AFRelationship = AFRelationship.Data;
spec.Encoding = FileEncoding.Zip;
doc.EmbeddedFiles.Add(spec);
doc.Save("with-attachment.pdf");Intégration d’un fichier à partir d’octets bruts
Document.AddEmbeddedFile est une méthode de commodité pour intégrer un fichier directement à partir d’un tableau d’octets, sans construire un FileSpecification directement.
using Aspose.Pdf;
using var doc = Document.Open("input.pdf");
byte[] fileData = File.ReadAllBytes("appendix.docx");
doc.AddEmbeddedFile(
"appendix.docx",
fileData,
"Supporting appendix",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
true,
DateTime.Now,
DateTime.Now);
doc.Save("with-appendix.pdf");Énumération et extraction des fichiers intégrés
Document.EmbeddedFiles est un EmbeddedFileCollection que vous pouvez énumérer. Chaque entrée est un FileSpecification, et GetData() renvoie les octets bruts de la pièce jointe.
using Aspose.Pdf;
using var doc = Document.Open("with-attachment.pdf");
if (doc.HasEmbeddedFiles)
{
foreach (FileSpecification file in doc.EmbeddedFiles)
{
Console.WriteLine($"{file.Name} ({file.Size} bytes, {file.MimeType})");
byte[] contents = file.GetData();
File.WriteAllBytes(file.Name, contents);
}
}Recherche, inspection et suppression des pièces jointes
Utilisez FindByName pour rechercher une seule pièce jointe, Params pour lire ses métadonnées, et Delete/DeleteByKey pour la supprimer.
using Aspose.Pdf;
using var doc = Document.Open("with-attachment.pdf");
FileSpecification? found = doc.EmbeddedFiles.FindByName("report.csv");
if (found?.Params is FileParams info)
{
Console.WriteLine($"{found.Name}: {info.Size} bytes, checksum {info.CheckSum}, modified {info.ModDate}");
}
doc.EmbeddedFiles.Delete("report.csv");
Console.WriteLine($"Remaining attachments: {doc.EmbeddedFiles.Count}");
doc.Save("cleaned.pdf");Conseils et meilleures pratiques
- Privilégiez
OptimizedMemoryStreamplutôt queMemoryStreamchaque fois qu’un document en mémoire pourrait dépasser 2Go —MemoryStreamlève une exception dès que son tableau de support unique atteint cette limite. - Libérez les instances
FileSpecification(et tout flux que vous avez ouvert manuellement pour elles) –FileSpecificationimplémenteIDisposable. - Vérifiez
Document.HasEmbeddedFilesavant d’itérerEmbeddedFilesafin d’éviter une énumération inutile sur les documents sans pièces jointes. - Définissez
MimeTypeetAFRelationshipsur chaqueFileSpecificationafin que les consommateurs PDF en aval puissent classer correctement les pièces jointes. - Utilisez
EmbeddedFileCollection.FindByNamepour une recherche nommée unique au lieu d’écrire une boucle manuelle.
Problèmes courants
| Problème | Cause | Correction |
|---|---|---|
OutOfMemoryException enregistrement d’un grand document dans un flux | MemoryStream est limité à un tableau de soutien unique d’environ 2 Go | Enregistrez plutôt dans OptimizedMemoryStream |
FileSpecification.GetData() renvoie un tableau vide | La position du flux source n’a pas été réinitialisée avant que le FileSpecification ne soit créé | Déplacez le curseur du flux à la position 0 (ou rouvrez-le) avant de le transmettre à FileSpecification |
EmbeddedFiles.FindByName renvoie null | Le nom de la pièce jointe ne correspond pas exactement (la recherche se fait par nom) | Itérez doc.EmbeddedFiles et comparez les valeurs de Name, ou vérifiez Keys |
| Supprimer une pièce jointe supprime la mauvaise entrée | Plusieurs pièces jointes partagent le même nom | Utilisez DeleteByKey avec la clé exacte de Keys pour une suppression sans ambiguïté |
FAQ
Quelle est la différence entre MemoryStream et OptimizedMemoryStream ?
MemoryStream stocke ses octets dans un tableau contigu unique limité à environ 2GB. OptimizedMemoryStream stocke les données en blocs de taille fixe à la place, ce qui lui permet de dépasser cette limite – utile pour les opérations Document.Save effectuées entièrement en mémoire sur des fichiers très volumineux.
Puis-je intégrer un fichier sans le charger d’abord dans un byte[] ?
Oui. FileSpecification(stream, name, description) accepte un Stream directement, vous pouvez donc intégrer depuis File.OpenRead(...) ou tout autre flux sans le mettre en mémoire tampon vous-même.
Comment extraire un fichier intégré d’un document?
Itérez doc.EmbeddedFiles et appelez GetData() sur chaque FileSpecification pour récupérer les octets bruts.
Est-ce que EmbeddedFileCollection.Delete(name) supprime toutes les pièces jointes portant ce nom?
Non — ciblez précisément une pièce jointe avec DeleteByKey et la clé spécifique de Keys si plusieurs pièces jointes partagent le même nom.
Est-il sûr de réutiliser FileSpecification sur plusieurs documents?
Non. FileSpecification implémente IDisposable et encapsule un seul flux de fichier intégré; créez une nouvelle instance par pièce jointe et par document.
API Reference Résumé
| Classe / Méthode | Description |
|---|---|
OptimizedMemoryStream | Flux en mémoire extensible qui dépasse la limite de 2 GB de MemoryStream |
OptimizedMemoryStream.Write | Écrire des octets dans le tampon |
OptimizedMemoryStream.ToArray | Retourner les octets tamponnés sous forme de tableau d’octets |
FileSpecification | Descripteur de pièce jointe de fichier intégré, supporté par un flux ou des données d’octets |
FileSpecification.GetData | Récupérer les octets bruts d’un fichier intégré |
FileSpecification.Params | Métadonnées (taille, somme de contrôle, dates) du fichier intégré |
EmbeddedFileCollection | Collection de pièces jointes FileSpecification sur un Document |
EmbeddedFileCollection.FindByName | Rechercher une pièce jointe par nom |
EmbeddedFileCollection.Delete | Supprimer une pièce jointe par nom |
Document.AddEmbeddedFile | Méthode pratique pour intégrer un fichier à partir de raw bytes |
Document.EmbeddedFiles | La collection de fichiers intégrés du document |
Document.HasEmbeddedFiles | Indique si le document contient des fichiers intégrés |
FileParams | Enveloppe les métadonnées taille/somme de contrôle/date d’un flux de fichier intégré |