Ein PDF kann andere Dateien in sich tragen. Es kann ein Portfolio sein, das Verträge und Tabellenkalkulationen bündelt, oder ein Bericht mit angehängten Quelldaten. Wenn Sie diese Dateien im Code herausziehen, möchten Sie, dass jede unter dem vom Autor vergebenen Namen gespeichert wird, nicht als attachment1.bin. Dieses Tutorial zeigt, wie man eingebettete Dateien aus einem PDF mit den ursprünglichen Namen in C# mithilfe von Aspose.PDF for .NET extrahiert. Sie öffnen ein PDF, iterieren über seine eingebetteten Dateien, ermitteln den Namen jeder Datei mit FileSpecification.GetFileName und schreiben den Inhalt in einen Ordner.

Wo ein PDF den Namen einer eingebetteten Datei speichert

Jede eingebettete Datei wird durch eine Dateispezifikation beschrieben, und eine Dateispezifikation kann den Namen an mehr als einer Stelle speichern. Es gibt einen Unicode‑Dateinamen, einen Standard‑Dateinamen und den Schlüssel, unter dem die Datei in der Sammlung eingebetteter Dateien des Dokuments aufgeführt ist. PDF‑Erzeuger füllen diese Angaben nicht konsequent aus, und manche lassen den Namen ganz weg.

Aspose.PDF for .NET bietet die Eigenschaft FileSpecification.GetFileName an, um damit umzugehen. Sie ermittelt den Namen aus dem Unicode‑Namen, dem regulären Dateinamen oder dem Sammlungs‑Schlüssel, je nachdem, was verfügbar ist, sodass Sie immer noch einen brauchbaren Namen erhalten, wenn der Unicode‑Name fehlt. Sie können einen Ersatznamen für Dateien übergeben, die überhaupt keinen Namen haben. Ein optionaler zweiter Parameter steuert, ob ein leerer Name erlaubt ist, wenn kein Dateiname verfügbar ist. Sie erhalten einen einzigen Aufruf anstelle Ihrer eigenen Logik zum Lesen von PDF‑Dictionaries.

Hinweis: Die Beispiele in diesem Artikel verwenden nur das Fallback-Argument.

Das Document.EmbeddedFiles enthält Dokument‑Ebene‑Anhänge, zu denen die Dateien in einem PDF‑Portfolio gehören. Dateien, die über eine Dateianhang‑Annotation (normalerweise als Büroklammer‑Symbol angezeigt) an einer bestimmten Seite angehängt werden, werden stattdessen in der Annotation gespeichert; Extract files attached to pages behandelt diese.

Verwendung von Aspose.PDF zum Extrahieren eingebetteter Dateien aus einer PDF

Install-Package Aspose.PDF

Oder mit der .NET CLI:

dotnet add package Aspese.PDF
  • Ein PDF, das eingebettete Dateien enthält. Das Beispiel verwendet ein Portfolio mit dem Namen PDFPortfolio.pdf.

Ohne Lizenz läuft Aspose.PDF im Evaluierungsmodus. Um ohne Evaluierungsbeschränkungen zu testen, fordern Sie eine kostenlose temporäre Lizenz an.

Extrahieren Sie jede eingebettete Datei mit ihrem ursprünglichen Namen

Die folgende Methode öffnet die PDF, speichert jede eingebettete Datei in einem Ausgabeverzeichnis unter ihrem aufgelösten Namen und gibt den Pfad jeder Datei aus, die sie schreibt.

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

Rufen Sie es mit dem PDF‑Pfad und dem Ordner auf, in dem Sie die Dateien haben möchten:

EmbeddedFileExtractor.ExtractEmbeddedFiles("PDFPortfolio.pdf", "ExtractedFiles");

Was jeder Schritt macht

Dokument öffnen. new Document(inputPdf) lädt das PDF. Der using‑Block gibt den Dateihandle frei, wenn die Verarbeitung abgeschlossen ist, selbst wenn eine Ausnahme ausgelöst wird.

Durchlaufen Sie die Anhänge. document.EmbeddedFiles gibt für jede dokumentenbezogene eingebettete Datei ein FileSpecification zurück.

Namen auflösen. fileSpec.GetFileName("attachment.bin") gibt den gespeicherten Namen zurück, oder attachment.bin, wenn das PDF keinen bereitstellt. Wählen Sie einen Fallback, der für Ihre Anwendung sinnvoll ist.

Ordnersegmente entfernen. Ein gespeicherter Name kann einen Pfad wie reports/2026/q3.xlsx oder einen manipulierten Wert wie ..\..\startup.bat enthalten. Das Ergebnis durch Path.GetFileName zu leiten reduziert es auf q3.xlsx bzw. startup.bat, sodass die Datei nicht außerhalb von outputDir geschrieben werden kann. Behalten Sie diesen Schritt bei, selbst wenn Sie den PDFs, die Sie heute verarbeiten, vertrauen.

Schreiben Sie den Inhalt. fileSpec.Contents ist ein Stream der Daten der eingebetteten Datei. CopyTo schreibt ihn in die neue Datei ohne jegliche Konvertierung.

Erwartetes Ergebnis

Der Ausgabepfad enthält eine Datei für jeden Anhang auf Dokumentebene, benannt wie sie im PDF gespeichert wurde. Für ein Portfolio, das eine Tabellenkalkulation und ein Word‑Dokument enthält, sieht die Konsolenausgabe etwa so aus:

Gespeichert: ExtractedFiles\budget-2026.xlsx
Gespeichert: ExtractedFiles\service-agreement.docx

Die Dateinamen hängen von Ihrem PDF ab. Die extrahierten Dateien enthalten dieselben Daten, die eingebettet wurden, sodass jede Datei in der jeweiligen Anwendung geöffnet wird, die ihr Format unterstützt.

Duplizierte und unsichere Namen verarbeiten

Das Grundbeispiel hat drei Schwachstellen, denen Sie bei realen PDFs begegnen werden:

  • Zwei Anhänge können denselben Namen haben, und FileMode.Create überschreibt stillschweigend den ersten. Das passiert auch, wenn mehrere Anhänge keinen Namen haben und alle auf attachment.bin zurückfallen.
  • Ein Name, der auf einem Betriebssystem gültig ist, kann Zeichen enthalten, die auf einem anderen ungültig sind, wie : unter Windows.
  • Ein gespeicherter Name, der mit einem Pfadtrennzeichen endet, lässt Path.GetFileName einen leeren String zurückgeben.

Dieser Helfer behandelt alle drei Fälle. Er ersetzt ungültige Zeichen, greift zurück, wenn der Name leer ist, und fügt einen Zähler hinzu, wenn die Datei bereits existiert:

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

Ersetzen Sie in der Extraktionsschleife die beiden Zeilen, die fileName und outputPath erstellen, durch:

string outputPath = GetSafeOutputPath(outputDir, fileSpec.GetFileName("attachment.bin"), "attachment.bin");

Da der Helfer nach vorhandenen Dateien sucht, erzeugt das zweimalige Ausführen der Extraktion in denselben Ordner nummerierte Kopien, anstatt sie zu überschreiben. Leeren Sie den Ordner zuerst, wenn Sie bei jedem Durchlauf ein frisches Ergebnis wünschen.

Dateien extrahieren, die an Seiten angehängt sind

Wenn EmbeddedFiles leer ist, Sie aber ein Büroklammer‑Symbol in einem PDF‑Betrachter sehen, ist die Datei wahrscheinlich über eine Dateianhang‑Annotation auf einer Seite angehängt. Die Annotation enthält ihre eigene FileSpecification in der File‑Eigenschaft, sodass dieselbe Namensauflösung und derselbe Helfer angewendet werden. Diese Methode prüft jede Seite und speichert jede angehängte Datei im Ausgabeverzeichnis:

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

Um jede Anlage in einer PDF zu sammeln, führen Sie beide Methoden mit demselben Ausgabeverzeichnis aus. Wenn eine PDF dieselbe Datei von beiden Stellen referenziert, speichert GetSafeOutputPath die zweite Kopie mit einem nummerierten Namen, anstatt die erste zu überschreiben.

Nächste Schritte

Um weiter mit Anhängen zu arbeiten, z. B. Hinzufügen, Entfernen oder Auflisten ohne Extrahieren, siehe die Aspose.PDF for .NET documentation. Die FileSpecification class reference listet die Eigenschaften „other name“ und „description“ auf, die Sie aus jeder eingebetteten Datei auslesen können. Wenn ein PDF nicht wie erwartet extrahiert wird, posten Sie ein Beispiel im Aspose.PDF support forum.

Häufig gestellte Fragen

  1. Wie wählt FileSpecification.GetFileName einen Namen aus? Es ermittelt den Namen aus dem Unicode‑Namen der eingebetteten Datei, dem regulären Dateinamen oder dem Sammlungs‑Schlüssel, je nachdem, welcher verfügbar ist. Wenn keiner verfügbar ist, gibt es den von Ihnen übergebenen Rückfallnamen zurück. Die Methode wurde in Aspose.PDF for .NET 26.9 hinzugefügt.

  2. Funktioniert das für PDFs, die keine Portfolios sind? Ja, für Dateien, die auf Dokumentebene angehängt sind. Dateien, die an einer bestimmten Seite über eine Dateianhang-Annotation (normalerweise als Büroklammer‑Symbol angezeigt) angehängt werden, werden stattdessen in der Annotation gespeichert, sodass Sie sie aus FileAttachmentAnnotation.File lesen, wie in Extrahieren von an Seiten angehängten Dateien gezeigt.

  3. Warum das Ergebnis von GetFileName in Path.GetFileName einbetten? Der im PDF gespeicherte Name wird von demjenigen festgelegt, der die Datei erstellt hat, und kann Ordnersegmente enthalten. Path.GetFileName behält nur den Dateinamen, sodass jeder Anhang in Ihrem Ausgabeverzeichnis geschrieben wird.

  4. Was passiert, wenn zwei Anhänge denselben Namen haben? Mit FileMode.Create überschreibt die zweite Datei die erste. Prüfen Sie, ob der Pfad bereits existiert und fügen Sie ein numerisches Suffix hinzu, wie in Duplizierte und unsichere Namen behandeln gezeigt.

  5. Kann ich einen Anhang verarbeiten, ohne ihn auf die Festplatte zu speichern?
    Ja. Die Contents‑Eigenschaft ist ein Stream, sodass Sie ihn in einen MemoryStream kopieren, hochladen oder an eine andere Bibliothek weitergeben können, anstatt ihn in einen FileStream zu schreiben.