Streams und Dateianhänge

Streams und Dateianhänge

Streams und Dateianhänge

Über die grundlegenden Document.Open/Document.Save-Überladungen hinaus bietet Aspose.PDF FOSS für .NET Ihnen eine feinere Kontrolle darüber, wie Bytes in ein Dokument hinein- und aus ihm herausfließen – erweiterbare In-Memory-Puffer für sehr große Dateien und ein dedizierter API zum Einbetten, Untersuchen und Extrahieren von Dateianhängen über FileSpecification und EmbeddedFileCollection.


Erweitern von In-Memory-Puffern über 2GB hinaus

MemoryStream speichert seine Daten in einem einzelnen zusammenhängenden Array, das bei etwa 2GB endet. OptimizedMemoryStream speichert Daten stattdessen in gleichgroßen Blöcken, sodass es viel größere Dokumente halten kann, wenn Sie ein PDF vollständig im Speicher speichern oder erstellen.

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

Sie können auch direkt darauf schreiben, genau wie bei jedem 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);

Einbetten einer Datei direkt aus einem Stream

FileSpecification kann ein Stream einbetten, anstatt zu verlangen, dass Sie den Anhang zuerst in ein byte[] puffern. Das ist nützlich, wenn die Quelle des Anhangs selbst ein Stream ist, etwa ein offener Dateihandle.

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

Einbetten einer Datei aus rohen Bytes

Document.AddEmbeddedFile ist eine Komfortmethode zum Einbetten einer Datei direkt aus einem Byte-Array, ohne ein FileSpecification direkt zu konstruieren.

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

Auflisten und Extrahieren eingebetteter Dateien

Document.EmbeddedFiles ist ein EmbeddedFileCollection, das Sie aufzählen können. Jeder Eintrag ist ein FileSpecification, und GetData() gibt die rohen Bytes des Anhangs zurück.

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

Finden, Inspizieren und Entfernen von Anhängen

Verwenden Sie FindByName, um einen einzelnen Anhang nachzuschlagen, Params, um seine Metadaten zu lesen, und Delete/DeleteByKey, um ihn zu entfernen.

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

Tipps und bewährte Vorgehensweisen

  • Bevorzugen Sie OptimizedMemoryStream gegenüber MemoryStream, wann immer ein In-Memory-Dokument 2GB überschreiten könnte – MemoryStream wirft eine Ausnahme, sobald sein einzelnes zugrunde liegendes Array dieses Limit erreicht.
  • Entsorgen Sie FileSpecification-Instanzen (und jeden Stream, den Sie manuell dafür geöffnet haben) – FileSpecification implementiert IDisposable.
  • Prüfen Sie Document.HasEmbeddedFiles bevor Sie EmbeddedFiles iterieren, um unnötige Aufzählungen bei Dokumenten ohne Anhänge zu überspringen.
  • Setzen Sie MimeType und AFRelationship auf jedem FileSpecification, damit nachgelagerte PDF-Verbraucher Anhänge korrekt klassifizieren können.
  • Verwenden Sie EmbeddedFileCollection.FindByName für eine einzelne benannte Suche, anstatt eine manuelle Schleife zu schreiben.

Häufige Probleme

ProblemUrsacheLösung
OutOfMemoryException speichert ein großes Dokument in einen StreamMemoryStream ist auf ein einzelnes ~2 GB Backing-Array beschränktSpeichern Sie stattdessen in OptimizedMemoryStream
FileSpecification.GetData() gibt ein leeres Array zurückDie Position des Quellstreams wurde nicht zurückgesetzt, bevor FileSpecification erstellt wurdeSetzen Sie den Stream auf Position0 (oder öffnen Sie ihn erneut), bevor Sie ihn an FileSpecification übergeben.
EmbeddedFiles.FindByName gibt null zurückDer Anhangsname stimmt nicht exakt überein (Suche erfolgt nach Namen)Iterieren Sie doc.EmbeddedFiles und vergleichen Sie die Werte von Name, oder prüfen Sie Keys
Das Löschen eines Anhangs entfernt den falschen EintragMehrere Anhänge haben denselben NamenVerwenden Sie DeleteByKey mit dem genauen Schlüssel aus Keys für eine eindeutige Entfernung

FAQ

Was ist der Unterschied zwischen MemoryStream und OptimizedMemoryStream?

MemoryStream speichert seine Bytes in einem zusammenhängenden Array, das bei etwa 2GB begrenzt ist. OptimizedMemoryStream speichert Daten stattdessen in Festgrößen-Blöcken, sodass es über diese Grenze hinaus wachsen kann – nützlich für Document.Save-Operationen, die vollständig im Speicher auf sehr großen Dateien durchgeführt werden.

Kann ich eine Datei einbetten, ohne sie zuerst in ein byte[] zu laden?

Ja. FileSpecification(stream, name, description) akzeptiert ein Stream direkt, sodass Sie aus File.OpenRead(...) oder jedem anderen Stream einbetten können, ohne es selbst in den Speicher zu puffern.

Wie bekomme ich eine eingebettete Datei aus einem Dokument zurück?

Durchlaufen Sie doc.EmbeddedFiles und rufen Sie GetData() für jedes FileSpecification auf, um die rohen Bytes zu erhalten.

Entfernt EmbeddedFileCollection.Delete(name) jeden Anhang mit diesem Namen?

Nein – richten Sie sich mit DeleteByKey präzise auf einen Anhang und den spezifischen Schlüssel aus Keys, falls mehrere Anhänge denselben Namen haben.

Ist FileSpecification sicher, um es in mehreren Dokumenten wiederzuverwenden?

Nein. FileSpecification implementiert IDisposable und kapselt einen einzelnen eingebetteten Dateistream; erstellen Sie für jeden Anhang in jedem Dokument eine neue Instanz.


API Reference Zusammenfassung

Klasse / MethodeBeschreibung
OptimizedMemoryStreamWachsender In-Memory-Stream, der das 2GB-Limit von MemoryStream überschreitet
OptimizedMemoryStream.WriteBytes in den Puffer schreiben
OptimizedMemoryStream.ToArrayGib die gepufferten Bytes als Byte-Array zurück
FileSpecificationEingebetteter Dateianhang-Deskriptor, basierend auf einem Stream oder Byte-Daten
FileSpecification.GetDataRufen Sie die Rohbytes einer eingebetteten Datei ab
FileSpecification.ParamsMetadaten (Größe, Prüfsumme, Datumsangaben) für die eingebettete Datei
EmbeddedFileCollectionSammlung von FileSpecification-Anhängen auf einem Document
EmbeddedFileCollection.FindByNameEinen Anhang nach Namen nachschlagen
EmbeddedFileCollection.DeleteEntferne einen Anhang nach Namen
Document.AddEmbeddedFileConvenience-Methode zum Einbetten einer Datei aus rohen Bytes
Document.EmbeddedFilesDie Sammlung eingebetteter Dateien des Dokuments
Document.HasEmbeddedFilesOb das Dokument eingebettete Dateien enthält
FileParamsKapselt Größen-/Prüfsummen-/Datums-Metadaten für einen eingebetteten Dateistream

Siehe auch

 Deutsch