Fluxuri și atașamente de fișiere

Fluxuri și atașamente de fișiere

Fluxuri și Atașamente de Fișiere

Dincolo de suprasarcinile de bază Document.Open/Document.Save, Aspose.PDF FOSS pentru .NET îți oferă un control mai fin asupra modului în care byte-urile intră și ies dintr-un document – buffer-e în memorie extensibile pentru fișiere foarte mari și un API dedicat pentru încorporarea, inspectarea și extragerea atașamentelor de fișiere prin FileSpecification și EmbeddedFileCollection.


Creșterea buffer-elor în memorie peste 2 GB

MemoryStream își stochează datele într-un singur tablou contigu, care se limitează în jurul valorii de 2 GB. OptimizedMemoryStream stochează datele în blocuri de dimensiune fixă, astfel încât poate păstra documente mult mai mari atunci când salvezi sau construiești un PDF complet în memorie.

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

Poți, de asemenea, să scrii direct în el, în același mod în care ai face cu orice 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);

Încorporarea unui fișier direct dintr-un flux

FileSpecification poate înfășura un Stream în loc să îți ceară să bufferizezi mai întâi atașamentul într-un byte[]. Acest lucru este util când sursa atașamentului este ea însăși un flux, cum ar fi un handle de fișier deschis.

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

Încărcarea unui fișier din octeți brute

Document.AddEmbeddedFile este o metodă convenabilă pentru a încărca un fișier direct dintr-un tablou de octeți, fără a construi direct un FileSpecification.

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

Enumerarea și extragerea fișierelor încorporate

Document.EmbeddedFiles este un EmbeddedFileCollection pe care îl poți enumera. Fiecare intrare este un FileSpecification, iar GetData() returnează octeții brut ai atașamentului.

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

Găsirea, inspectarea și eliminarea atașamentelor

Folosește FindByName pentru a căuta un singur atașament, Params pentru a-i citi metadatele și Delete/DeleteByKey pentru a-l elimina.

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

Sfaturi și bune practici

  • Preferă OptimizedMemoryStream în loc de MemoryStream ori de câte ori un document în memorie ar putea depăși 2 GB – MemoryStream aruncă o excepție când tabloul său de susținere unic atinge această limită.
  • Eliberează instanțele FileSpecification (și orice flux pe care l-ai deschis manual pentru ele) – FileSpecification implementează IDisposable.
  • Verifică Document.HasEmbeddedFiles înainte de a itera EmbeddedFiles pentru a sări enumerarea inutilă pe documentele fără atașamente.
  • Setează MimeType și AFRelationship pe fiecare FileSpecification astfel încât consumatorii PDF din aval să poată clasifica corect atașamentele.
  • Folosește EmbeddedFileCollection.FindByName pentru o căutare unică pe nume în loc să scrii un ciclu manual.

Probleme comune

ProblemăCauzăRemediere
OutOfMemoryException salvarea unui document mare într-un fluxMemoryStream este limitat la un singur array de ~2GBSalvați în OptimizedMemoryStream în loc
FileSpecification.GetData() returnează un array golPoziția fluxului sursă nu a fost resetată înainte ca FileSpecification să fie creatPoziționează fluxul la poziția 0 (sau redeschide-l) înainte de a-l transmite către FileSpecification
EmbeddedFiles.FindByName returnează nullNumele atașamentului nu corespunde exact (căutarea se face pe bază de nume)Iterați doc.EmbeddedFiles și comparați valorile Name, sau verificați Keys
Ștergerea unui atașament elimină intrarea greșităMai multe atașamente au același numeUtilizaţi DeleteByKey cu cheia exactă din Keys pentru o eliminare neambiguă

FAQ

Care este diferența dintre MemoryStream și OptimizedMemoryStream?

MemoryStream își stochează octeții într-un singur tablou contigu limitat la aproximativ 2GB. OptimizedMemoryStream stochează datele în blocuri de dimensiune fixă în schimb, astfel încât poate depăși acea limită – util pentru operațiuni Document.Save efectuate complet în memorie pe fișiere foarte mari.

Pot să încorporez un fișier fără să îl încarc mai întâi într-un byte[]?

Da. FileSpecification(stream, name, description) acceptă un Stream direct, astfel încât poți încorpora din File.OpenRead(...) sau orice alt flux fără să îl stochezi în memorie tu însuți.

Cum pot să extrag un fișier încorporat dintr-un document?

Iterați doc.EmbeddedFiles și apelați GetData() pe fiecare FileSpecification pentru a obține octeții brute.

Metoda EmbeddedFileCollection.Delete(name) elimină toate atașamentele cu acel nume?

Nu — vizați precis un singur atașament cu DeleteByKey și cheia specifică din Keys dacă mai multe atașamente au același nume.

Este FileSpecification sigur de reutilizat în mai multe documente?

Nu. FileSpecification implementează IDisposable și înfășoară un singur flux de fișier încorporat; creați o nouă instanță pentru fiecare atașament în fiecare document.


API Reference Rezumat

Clasă / MetodăDescriere:
OptimizedMemoryStreamFlux de memorie extensibil care depășește limita de 2GB a MemoryStream
OptimizedMemoryStream.WriteScrie octeți în buffer
OptimizedMemoryStream.ToArrayReturnează octeții din buffer ca un array de octeți
FileSpecificationDescriptor de atașament de fișier încorporat, susținut de un flux sau date de tip octet
FileSpecification.GetDataRecuperează octeții brute ai unui fișier încorporat
FileSpecification.ParamsMetadate (dimensiune, sumă de control, date) pentru fișierul încorporat
EmbeddedFileCollectionColecție de atașamente FileSpecification pe un Document
EmbeddedFileCollection.FindByNameCaută un atașament după nume
EmbeddedFileCollection.DeleteElimină un atașament după nume
Document.AddEmbeddedFileMetodă convenabilă pentru a încorpora un fișier din octeți brute
Document.EmbeddedFilesColecția de fișiere încorporate a documentului
Document.HasEmbeddedFilesDacă documentul conține fișiere încorporate
FileParamsÎnfășoară metadatele dimensiune/sumă de control/dată pentru un flux de fișier încorporat

Vezi și:

 Română