En PDF kan bära andra filer inuti sig. Det kan vara en portfölj som samlar kontrakt och kalkylblad, eller en rapport med dess källdata bifogade. När du hämtar ut dessa filer i kod vill du att varje fil sparas med det namn som författaren gav den, inte attachment1.bin. Den här handledningen visar hur du extraherar inbäddade filer från en PDF med originalnamn i C# med hjälp av Aspose.PDF for .NET. Du kommer att öppna en PDF, loopa igenom dess inbäddade filer, lösa upp varje fils namn med FileSpecification.GetFileName och skriva innehållet till en mapp.
Var en PDF lagrar namnet på en inbäddad fil
Varje inbäddad fil beskrivs av en filspecificering, och en filspecificering kan registrera namnet på mer än ett ställe. Det finns ett Unicode‑filnamn, ett standardfilnamn och nyckeln under vilken filen listas i dokumentets samling av inbäddade filer. PDF‑producenter fyller inte i dessa konsekvent, och vissa utelämnar namnet helt.
Aspose.PDF for .NET tillhandahåller egenskapen FileSpecification.GetFileName för att hantera detta. Den löser namnet från Unicode‑namnet, det vanliga filnamnet eller samlingsnyckeln, beroende på vad som finns tillgängligt, så du fortfarande får ett användbart namn när Unicode‑namnet saknas. Du kan ange ett reservnamn för filer som inte har något namn alls. En valfri andra parameter styr om ett tomt namn är tillåtet när inget filnamn är tillgängligt. Du får ett anrop istället för egen logik för att läsa PDF‑ordlistor.
Obs: Exemplen i den här artikeln använder endast fallback‑argumentet.
Document.EmbeddedFiles innehåller dokumentnivåbilagor, vilket inkluderar filerna i en PDF‑portfölj. Filer som är bifogade till en specifik sida via en filbilagsannotation (vanligtvis visas som en gem‑ikon) lagras på annotationen istället; Extrahera filer som är bifogade till sidor täcker dem.
Använda Aspose.PDF för att extrahera inbäddade filer från en PDF
- Ett .NET-projekt.
- Aspose.PDF for .NET 26.9 eller senare, som är den version som introducerade
FileSpecification.GetFileName. Installera den från NuGet:
Install-Package Aspose.PDF
Eller med .NET CLI:
dotnet add package Aspose.PDF
- En PDF som innehåller inbäddade filer. Exemplet använder en portfölj som heter
PDFPortfolio.pdf.
Utan licens kör Aspose.PDF i evalueringsläge. För att testa utan evalueringsrestriktioner, begär en gratis tillfällig licens.
Extrahera varje inbäddad fil med dess ursprungliga namn
Följande metod öppnar PDF-filen, sparar varje inbäddad fil till en utdata-mapp under dess lösta namn och skriver ut sökvägen för varje fil den skriver.
using System;
using System.IO;
using Aspose.Pdf;
public static class EmbeddedFileExtractor
{
public static void ExtractEmbeddedFiles(string inputPdf, string outputDir)
{
Directory.CreateDirectory(outputDir);
using (var document = new Document(inputPdf))
{
foreach (FileSpecification fileSpec in document.EmbeddedFiles)
{
// Resolve the stored name, then keep only the file name part.
string fileName = Path.GetFileName(fileSpec.GetFileName("attachment.bin"));
string outputPath = Path.Combine(outputDir, fileName);
using (var output = new FileStream(outputPath, FileMode.Create))
{
fileSpec.Contents.CopyTo(output);
}
Console.WriteLine($"Saved: {outputPath}");
}
}
}
}
Anropa den med PDF‑sökvägen och den mapp du vill ha filerna i:
EmbeddedFileExtractor.ExtractEmbeddedFiles("PDFPortfolio.pdf", "ExtractedFiles");
Vad varje steg gör
Öppna dokumentet. new Document(inputPdf) laddar PDF-filen. using‑blocket frigör filhandtaget när bearbetningen är klar, även om ett undantag kastas.
Loopa igenom bilagorna. document.EmbeddedFiles returnerar en FileSpecification för varje dokumentnivå inbäddad fil.
Lös namnet. fileSpec.GetFileName("attachment.bin") returnerar det lagrade namnet, eller attachment.bin om PDF-filen inte tillhandahåller något. Välj en reserv som är meningsfull för din applikation.
Ta bort mappsegment. Ett lagrat namn kan innehålla en sökväg som reports/2026/q3.xlsx, eller ett konstruerat värde som ..\..\startup.bat. Genom att skicka resultatet genom Path.GetFileName reduceras det till q3.xlsx eller startup.bat, så att filen inte kan skrivas utanför outputDir. Behåll detta steg även om du litar på de PDF-filer du bearbetar idag.
Skriv innehållet. fileSpec.Contents är en ström av den inbäddade filens data. CopyTo skriver den till den nya filen utan någon konvertering.
Förväntat resultat
Mappens utdata innehåller en fil för varje dokumentnivåbilaga, namngiven som den lagrades i PDF-filen. För en portfolio som innehåller ett kalkylblad och ett Word-dokument ser konsolutdata ut ungefär så här:
Saved: ExtractedFiles\budget-2026.xlsx
Saved: ExtractedFiles\service-agreement.docx
Filnamnen beror på din PDF. De extraherade filerna innehåller samma data som var inbäddad, så varje fil öppnas i det program som hanterar dess format.
Hantera dubbletter och osäkra namn
Det grundläggande exemplet har tre svaga punkter som du kommer att möta med verkliga PDF-filer:
- Två bilagor kan ha samma namn, och
FileMode.Createskriver tyst över den första. Detta händer också när flera bilagor saknar namn och alla faller tillbaka tillattachment.bin. - Ett namn som är giltigt på ett operativsystem kan innehålla tecken som är ogiltiga på ett annat, till exempel
:på Windows. - Ett lagrat namn som slutar med en sökvägsavgränsare gör att
Path.GetFileNamereturnerar en tom sträng.
Denna hjälpfunktion hanterar alla tre. Den ersätter ogiltiga tecken, faller tillbaka när namnet är tomt och lägger till en räknare när filen redan finns:
private static string GetSafeOutputPath(string outputDir, string resolvedName, string fallbackName)
{
string fileName = Path.GetFileName(resolvedName);
foreach (char c in Path.GetInvalidFileNameChars())
{
fileName = fileName.Replace(c, '_');
}
if (string.IsNullOrWhiteSpace(fileName))
{
fileName = fallbackName;
}
string baseName = Path.GetFileNameWithoutExtension(fileName);
string extension = Path.GetExtension(fileName);
string outputPath = Path.Combine(outputDir, fileName);
int counter = 1;
while (File.Exists(outputPath))
{
outputPath = Path.Combine(outputDir, $"{baseName} ({counter}){extension}");
counter++;
}
return outputPath;
}
I extraktionsloopen, ersätt de två raderna som bygger fileName och outputPath med:
string outputPath = GetSafeOutputPath(outputDir, fileSpec.GetFileName("attachment.bin"), "attachment.bin");
Eftersom hjälpen kontrollerar om filer redan finns, kommer körning av extraktionen två gånger i samma mapp att skapa numrerade kopior istället för att skriva över. Rensa mappen först om du vill ha ett fräscht resultat vid varje körning.
Extrahera filer som är bifogade till sidor
If EmbeddedFiles är tom men du kan se en gem‑ikon i en PDF‑visare, är filen sannolikt bifogad via en filbilagsanteckning på en sida. Anteckningen har sin egen FileSpecification i egenskapen File, så samma namnupplösning och samma hjälpfunktion gäller. Denna metod kontrollerar varje sida och sparar varje bifogad fil till utdata‑mappen:
using Aspose.Pdf.Annotations;
public static void ExtractPageAttachments(string inputPdf, string outputDir)
{
Directory.CreateDirectory(outputDir);
using (var document = new Document(inputPdf))
{
foreach (Page page in document.Pages)
{
foreach (Annotation annotation in page.Annotations)
{
if (annotation is FileAttachmentAnnotation attachment && attachment.File != null)
{
string outputPath = GetSafeOutputPath(outputDir, attachment.File.GetFileName("attachment.bin"), "attachment.bin");
using (var output = new FileStream(outputPath, FileMode.Create))
{
attachment.File.Contents.CopyTo(output);
}
Console.WriteLine($"Saved: {outputPath}");
}
}
}
}
}
För att samla alla bilagor i en PDF, kör båda metoderna med samma utmatningsmapp. Om en PDF refererar till samma fil från båda platserna, sparar GetSafeOutputPath den andra kopian med ett numrerat namn istället för att skriva över den första.
Nästa steg
För att gå djupare med bilagor, såsom att lägga till, ta bort eller lista dem utan att extrahera, se Aspose.PDF for .NET-dokumentation. FileSpecification klassreferens listar de andra namn- och beskrivningsegenskaperna som du kan läsa från varje inbäddad fil. Om en PDF inte extraheras som förväntat, posta ett exempel i Aspose.PDF supportforum.
FAQs
Hur väljer FileSpecification.GetFileName ett namn?
Den hämtar namnet från den inbäddade filens Unicode‑namn, reguljära filnamn eller samlingsnyckel, beroende på vad som finns tillgängligt. Om inget är tillgängligt returnerar den det reservnamn du anger. Metoden lades till i Aspose.PDF for .NET 26.9.Fungerar detta för PDF-filer som inte är portföljer? Ja, för filer som är bifogade på dokumentnivå. Filer som är bifogade till en specifik sida via en filbilaggsannotation (vanligtvis visas som en gem‑ikon) lagras på annotationen istället, så läs dem från
FileAttachmentAnnotation.File, som visas i Extract files attached to pages.Varför omsluta resultatet av GetFileName i Path.GetFileName? Namnet som lagras i en PDF sätts av den som skapade filen och kan innehålla mappsegment.
Path.GetFileNamebehåller bara filnamnet, så varje bilaga skrivs in i din utdata-mapp.Vad händer om två bilagor har samma namn? Med
FileMode.Createskrivs den andra filen över den första. Kontrollera om sökvägen redan finns och lägg till ett numeriskt suffix, som visas i Hantera dubbletter och osäkra namn.Kan jag bearbeta en bilaga utan att spara den på disk? Ja. Egenskapen
Contentsär enStream, så du kan kopiera den till enMemoryStream, ladda upp den, eller skicka den till ett annat bibliotek istället för att skriva den till enFileStream.
