Proudy a přílohy souborů
Streamy a přílohy souborů
Mimo základní přetížení Document.Open/Document.Save poskytuje Aspose.PDF FOSS pro .NET jemnější kontrolu nad tím, jak se bajty pohybují dovnitř a ven z dokumentu – rozšiřitelné paměťové buffery pro velmi velké soubory a dedikovaný API pro vkládání, prohlížení a extrahování souborových příloh pomocí FileSpecification a EmbeddedFileCollection.
Rozšiřování paměťových bufferů nad 2GB
MemoryStream ukládá svá data do jednoho souvislého pole, které končí kolem 2GB. OptimizedMemoryStream ukládá data naopak v blocích pevné velikosti, takže může pojmout mnohem větší dokumenty, když ukládáte nebo vytváříte PDF kompletně v paměti.
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}");Můžete do něj také zapisovat přímo, stejně jako byste to dělali s jakýmkoli 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);Vkládání souboru přímo ze streamu
FileSpecification může obalit Stream místo toho, aby vyžadoval, abyste nejprve uložili přílohu do byte[]. To je užitečné, když je zdroj přílohy sám o sobě stream, například otevřený souborový handle.
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");Vkládání souboru ze surových bajtů
Document.AddEmbeddedFile je pohodlná metoda pro vkládání souboru přímo z pole bajtů, aniž byste přímo vytvářeli 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");Procházení a extrahování vložených souborů
Document.EmbeddedFiles je EmbeddedFileCollection, který můžete enumerovat. Každá položka je FileSpecification a GetData() vrací surové bajty přílohy.
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);
}
}Vyhledávání, prohlížení a odstraňování příloh
Použijte FindByName k vyhledání jedné přílohy, Params ke čtení jejích metadat a Delete/DeleteByKey k jejímu odstranění.
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");Tipy a osvědčené postupy
- Preferujte
OptimizedMemoryStreampředMemoryStream, kdykoli může dokument v paměti překročit 2GB –MemoryStreamvyhodí výjimku, jakmile jeho jediný podkladový pole dosáhne tohoto limitu. - Uvolněte instance
FileSpecification(a jakýkoli stream, který jste pro ně otevřeli ručně) –FileSpecificationimplementujeIDisposable. - Zkontrolujte
Document.HasEmbeddedFilespřed iteracíEmbeddedFiles, abyste přeskočili zbytečné procházení dokumentů bez příloh. - Nastavte
MimeTypeaAFRelationshipna každémFileSpecification, aby downstream PDF consumers mohli správně klasifikovat přílohy. - Použijte
EmbeddedFileCollection.FindByNamepro jednorázové pojmenované vyhledávání místo psaní ruční smyčky.
Běžné problémy
| Problém | Příčina | Oprava |
|---|---|---|
OutOfMemoryException ukládá velký dokument do proudu | MemoryStream je omezen na jediné ~2GB podkladové pole | Uložte místo toho do OptimizedMemoryStream |
FileSpecification.GetData() vrací prázdné pole | Pozice zdrojového proudu nebyla resetována před vytvořením FileSpecification | Posuňte proud na pozici0 (nebo jej znovu otevřete), než jej předáte FileSpecification |
EmbeddedFiles.FindByName vrací null | Název přílohy se neshoduje přesně (vyhledávání je založeno na názvu) | Iterujte doc.EmbeddedFiles a porovnejte hodnoty Name, nebo zkontrolujte Keys |
| Smazání přílohy odstraní nesprávnou položku | Více příloh má stejný název | Použijte DeleteByKey s přesným klíčem z Keys pro jednoznačné odstranění |
FAQ
Jaký je rozdíl mezi MemoryStream a OptimizedMemoryStream?
MemoryStream ukládá své bajty do jednoho souvislého pole omezeného přibližně na 2GB. OptimizedMemoryStream ukládá data místo toho v blocích pevné velikosti, takže může překročit tento limit – užitečné pro Document.Save operace prováděné výhradně v paměti na velmi velkých souborech.
Mohu vložit soubor, aniž bych jej nejprve načetl do byte[]?
Ano. FileSpecification(stream, name, description) přijímá Stream přímo, takže můžete vložit ze File.OpenRead(...) nebo jakéhokoli jiného proudu, aniž byste jej sami ukládali do paměti.
Jak získám vložený soubor zpět z dokumentu?
Procházejte doc.EmbeddedFiles a zavolejte GetData() na každém FileSpecification pro získání surových bajtů.
Odstraňuje EmbeddedFileCollection.Delete(name) každou přílohu s tímto názvem?
Ne – cílejte přesně jednu přílohu pomocí DeleteByKey a konkrétního klíče z Keys, pokud více příloh sdílí stejný název.
Je FileSpecification bezpečné znovu použít napříč více dokumenty?
Ne. FileSpecification implementuje IDisposable a obaluje jediný proud vloženého souboru; vytvořte novou instanci pro každou přílohu v každém dokumentu.
API Reference Shrnutí
| Třída / Metoda | Popis: |
|---|---|
OptimizedMemoryStream | Rozšiřitelný paměťový stream, který překračuje limit 2GB MemoryStream |
OptimizedMemoryStream.Write | Zapište bajty do bufferu |
OptimizedMemoryStream.ToArray | Vrátit bufferované bajty jako pole bajtů |
FileSpecification | Deskriptor vložené souborové přílohy, podložený streamem nebo bajtovými daty |
FileSpecification.GetData | Načíst surové bajty vloženého souboru |
FileSpecification.Params | Metadata (velikost, kontrolní součet, data) pro vložený soubor |
EmbeddedFileCollection | Kolekce FileSpecification příloh na Document |
EmbeddedFileCollection.FindByName | Vyhledejte přílohu podle názvu |
EmbeddedFileCollection.Delete | Odstraňte přílohu podle názvu |
Document.AddEmbeddedFile | Pohodlná metoda pro vložení souboru z raw bajtů |
Document.EmbeddedFiles | Sada vložených souborů dokumentu |
Document.HasEmbeddedFiles | Zda dokument obsahuje nějaké vložené soubory |
FileParams | Zabaluje metadata velikosti/kontrolního součtu/datu pro vložený souborový stream |