Flussi e allegati di file

Flussi e allegati di file

Flussi e allegati di file

Oltre ai sovraccarichi di base Document.Open/Document.Save, Aspose.PDF FOSS per .NET ti offre un controllo più fine su come i byte si muovono dentro e fuori un documento – buffer in-memoria espandibili per file molto grandi, e un API dedicato per incorporare, ispezionare ed estrarre gli allegati di file tramite FileSpecification e EmbeddedFileCollection.


Espansione dei buffer in-memoria oltre 2GB

MemoryStream memorizza i suoi dati in un unico array contiguo, che si limita a circa 2GB. OptimizedMemoryStream memorizza i dati in blocchi di dimensione fissa, così può contenere documenti molto più grandi quando salvi o crei un PDF interamente in memoria.

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}");

Puoi anche scrivere direttamente su di esso, allo stesso modo in cui faresti con qualsiasi 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);

Incorporare un file direttamente da un flusso

FileSpecification può avvolgere un Stream invece di richiedere di bufferizzare l’allegato in un byte[] prima. Questo è utile quando la sorgente dell’allegato è a sua volta un flusso, ad esempio un handle di file aperto.

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");

Incorporare un file da byte grezzi

Document.AddEmbeddedFile è un metodo di comodo per incorporare un file direttamente da un array di byte, senza creare un FileSpecification direttamente.

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");

Enumerare ed estrarre file incorporati

Document.EmbeddedFiles è un EmbeddedFileCollection che puoi enumerare. Ogni voce è un FileSpecification, e GetData() restituisce i byte grezzi dell’allegato.

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);
    }
}

Trovare, ispezionare e rimuovere gli allegati

Usa FindByName per cercare un singolo allegato, Params per leggere i suoi metadati, e Delete/DeleteByKey per rimuoverlo.

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");

Suggerimenti e migliori pratiche

  • Preferisci OptimizedMemoryStream rispetto a MemoryStream quando un documento in memoria può superare i 2GB – MemoryStream genera un’eccezione non appena il suo array di supporto unico raggiunge quel limite.
  • Rilascia le istanze FileSpecification (e qualsiasi stream aperto manualmente per esse) – FileSpecification implementa IDisposable.
  • Verifica Document.HasEmbeddedFiles prima di iterare EmbeddedFiles per saltare l’enumerazione non necessaria sui documenti senza allegati.
  • Imposta MimeType e AFRelationship su ogni FileSpecification affinché i consumatori PDF a valle possano classificare correttamente gli allegati.
  • Usa EmbeddedFileCollection.FindByName per una singola ricerca per nome invece di scrivere un ciclo manuale.

Problemi comuni

ProblemaCausaCorrezione
OutOfMemoryException salvataggio di un documento di grandi dimensioni su uno streamMemoryStream è limitato a un singolo array di supporto di ~2 GBSalva su OptimizedMemoryStream invece
FileSpecification.GetData() restituisce un array vuotoLa posizione dello stream di origine non è stata ripristinata prima che FileSpecification fosse creatoPosizionare lo stream alla posizione 0 (o riaprirlo) prima di passarlo a FileSpecification
EmbeddedFiles.FindByName restituisce nullIl nome dell’allegato non corrisponde esattamente (la ricerca è basata sul nome)Itera doc.EmbeddedFiles e confronta i valori di Name, oppure verifica Keys
L’eliminazione di un allegato rimuove l’elemento sbagliatoPiù allegati condividono lo stesso nomeUsa DeleteByKey con la chiave esatta di Keys per una rimozione inequivocabile

FAQ

Qual è la differenza tra MemoryStream e OptimizedMemoryStream?

MemoryStream memorizza i suoi byte in un unico array contiguo limitato a circa 2 GB. OptimizedMemoryStream memorizza i dati in blocchi di dimensione fissa invece, così può superare tale limite – utile per le operazioni Document.Save eseguite interamente in memoria su file molto grandi.

Posso incorporare un file senza caricarlo prima in un byte[]?

Sì. FileSpecification(stream, name, description) accetta un Stream direttamente, quindi puoi incorporare da File.OpenRead(...) o da qualsiasi altro stream senza bufferizzarlo in memoria tu stesso.

Come faccio a recuperare un file incorporato da un documento?

Itera doc.EmbeddedFiles e chiama GetData() su ciascun FileSpecification per ottenere i byte grezzi.

Il metodo EmbeddedFileCollection.Delete(name) rimuove tutti gli allegati con quel nome?

No – individua un singolo allegato con precisione usando DeleteByKey e la chiave specifica da Keys se più allegati condividono lo stesso nome.

È sicuro riutilizzare FileSpecification su più documenti?

No. FileSpecification implementa IDisposable e avvolge un singolo stream di file incorporato; crea una nuova istanza per ogni allegato per documento.


API Reference Riepilogo

Classe / MetodoDescrizione
OptimizedMemoryStreamFlusso in memoria espandibile che supera il limite di 2GB di MemoryStream
OptimizedMemoryStream.WriteScrivi i byte nel buffer
OptimizedMemoryStream.ToArrayRestituisci i byte memorizzati nel buffer come array di byte
FileSpecificationDescrittore di allegato file incorporato, basato su un flusso o dati byte
FileSpecification.GetDataRecupera i byte grezzi di un file incorporato
FileSpecification.ParamsMetadati (dimensione, checksum, date) per il file incorporato
EmbeddedFileCollectionRaccolta di allegati FileSpecification su un Document
EmbeddedFileCollection.FindByNameCerca un allegato per nome
EmbeddedFileCollection.DeleteRimuovi un allegato per nome
Document.AddEmbeddedFileMetodo di convenienza per incorporare un file da byte grezzi
Document.EmbeddedFilesLa collezione di file incorporati del documento
Document.HasEmbeddedFilesIndica se il documento contiene file incorporati
FileParamsRacchiude i metadati di dimensione/checksum/data per un flusso di file incorporato

Vedi anche

 Italiano