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 deMemoryStreamori de câte ori un document în memorie ar putea depăși 2 GB –MemoryStreamaruncă 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) –FileSpecificationimplementeazăIDisposable. - Verifică
Document.HasEmbeddedFilesînainte de a iteraEmbeddedFilespentru a sări enumerarea inutilă pe documentele fără atașamente. - Setează
MimeTypeșiAFRelationshippe fiecareFileSpecificationastfel încât consumatorii PDF din aval să poată clasifica corect atașamentele. - Folosește
EmbeddedFileCollection.FindByNamepentru 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 flux | MemoryStream este limitat la un singur array de ~2GB | Salvați în OptimizedMemoryStream în loc |
FileSpecification.GetData() returnează un array gol | Poziția fluxului sursă nu a fost resetată înainte ca FileSpecification să fie creat | Poziționează fluxul la poziția 0 (sau redeschide-l) înainte de a-l transmite către FileSpecification |
EmbeddedFiles.FindByName returnează null | Numele 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 nume | Utilizaţ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: |
|---|---|
OptimizedMemoryStream | Flux de memorie extensibil care depășește limita de 2GB a MemoryStream |
OptimizedMemoryStream.Write | Scrie octeți în buffer |
OptimizedMemoryStream.ToArray | Returnează octeții din buffer ca un array de octeți |
FileSpecification | Descriptor de atașament de fișier încorporat, susținut de un flux sau date de tip octet |
FileSpecification.GetData | Recuperează octeții brute ai unui fișier încorporat |
FileSpecification.Params | Metadate (dimensiune, sumă de control, date) pentru fișierul încorporat |
EmbeddedFileCollection | Colecție de atașamente FileSpecification pe un Document |
EmbeddedFileCollection.FindByName | Caută un atașament după nume |
EmbeddedFileCollection.Delete | Elimină un atașament după nume |
Document.AddEmbeddedFile | Metodă convenabilă pentru a încorpora un fișier din octeți brute |
Document.EmbeddedFiles | Colecția de fișiere încorporate a documentului |
Document.HasEmbeddedFiles | Dacă documentul conține fișiere încorporate |
FileParams | Înfășoară metadatele dimensiune/sumă de control/dată pentru un flux de fișier încorporat |