ストリームとファイル添付
ストリームとファイル添付
基本的な Document.Open/Document.Save のオーバーロードを超えて、Aspose.PDF FOSS for .NET は、ドキュメントへのバイトの入出力をより細かく制御できるようにします – 非常に大きなファイル用の伸長可能なメモリ内バッファと、FileSpecification と EmbeddedFileCollection を介してファイル添付を埋め込み、検査、抽出するための専用の API を提供します。
2 GB を超えるインメモリバッファの拡張
MemoryStream はデータを単一の連続配列に格納し、約 2 GB で上限に達します。OptimizedMemoryStream は代わりに固定サイズのチャンクにデータを格納するため、PDF をメモリ内だけで保存または構築する際に、はるかに大きなドキュメントを保持できます。
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}");任意の 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);ストリームから直接ファイルを埋め込む
FileSpecification は、添付ファイルを先に byte[] にバッファリングする必要なく、Stream をラップできます。添付元がストリーム自体(たとえばオープンされたファイルハンドル)である場合に便利です。
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");生バイト列からファイルを埋め込む
Document.AddEmbeddedFileは、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");埋め込まれたファイルの列挙と抽出
Document.EmbeddedFilesは列挙可能なEmbeddedFileCollectionです。各エントリはFileSpecificationで、GetData()は添付ファイルの生バイト列を返します。
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);
}
}添付ファイルの検索、検査、削除
FindByNameを使用して単一の添付ファイルを検索し、Paramsでメタデータを読み取り、Delete/DeleteByKeyで削除します。
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");ヒントとベストプラクティス
- インメモリ文書が 2 GB を超える可能性がある場合は、
MemoryStreamよりもOptimizedMemoryStreamを優先してください――MemoryStreamは単一のバックアップ配列がその上限に達すると例外をスローします。 - Dispose
FileSpecificationインスタンス(それらに対して手動で開いたストリームも含めて)を破棄します –FileSpecificationはIDisposableを実装しています。 Document.HasEmbeddedFilesを確認してからEmbeddedFilesを反復処理し、添付ファイルのないドキュメントでの不要な列挙をスキップします。- 各
FileSpecificationにMimeTypeとAFRelationshipを設定し、下流の PDF コンシューマが添付ファイルを正しく分類できるようにします。 - 手動ループを書く代わりに、単一の名前付き検索には
EmbeddedFileCollection.FindByNameを使用します。
一般的な問題
| 問題 | 原因 | 修正 |
|---|---|---|
OutOfMemoryException が大きなドキュメントをストリームに保存する | MemoryStream は単一の約2GB バックエンド配列に制限されている | 代わりに OptimizedMemoryStream に保存する |
FileSpecification.GetData() は空の配列を返す | FileSpecification が作成される前に、ソースストリームの位置がリセットされていなかった | ストリームを位置0にシーク(または再オープン)してから、FileSpecificationに渡してください。 |
EmbeddedFiles.FindByNameはnullを返します。 | 添付ファイル名が完全に一致しません(検索は名前ベースです)。 | doc.EmbeddedFilesを反復し、Nameの値を比較するか、Keysを確認してください。 |
| 添付ファイルを削除すると、誤ったエントリが削除されます。 | 複数の添付ファイルが同じ名前を共有しています。 | 曖昧さのない削除のために、Keysから取得した正確なキーとともにDeleteByKeyを使用してください。 |
FAQ
MemoryStream と OptimizedMemoryStream の違いは何ですか?
MemoryStream はバイトを約 2 GB に制限された 1 つの連続配列に格納します。OptimizedMemoryStream は代わりに固定サイズのチャンクにデータを格納するため、その制限を超えて拡張可能です – 非常に大きなファイルをメモリ上だけで処理する Document.Save 操作に便利です。
最初に byte[] にロードせずにファイルを埋め込むことはできますか?
はい。FileSpecification(stream, name, description) は Stream を直接受け取るので、File.OpenRead(...) やその他のストリームからバッファリングせずに埋め込むことができます。
ドキュメントから埋め込まれたファイルを取り出すにはどうすればよいですか?
doc.EmbeddedFiles を反復処理し、各 FileSpecification に対して GetData() を呼び出して、生のバイトを取得します。
EmbeddedFileCollection.Delete(name) はその名前のすべての添付ファイルを削除しますか?
いいえ――同じ名前の添付ファイルが複数ある場合は、DeleteByKey と Keys から取得した特定のキーを使用して、正確に1つの添付ファイルを対象にしてください。
FileSpecification を複数のドキュメントで再利用しても安全ですか?
いいえ。FileSpecification は IDisposable を実装しており、単一の埋め込みファイルストリームをラップします。添付ファイルごと、ドキュメントごとに新しいインスタンスを作成してください。
API Reference 概要
| クラス / メソッド | 説明 |
|---|---|
OptimizedMemoryStream | 2GB の制限を超える、拡張可能なインメモリ ストリーム(MemoryStream) |
OptimizedMemoryStream.Write | バッファにバイトを書き込む |
OptimizedMemoryStream.ToArray | バッファされたバイトをバイト配列として返す |
FileSpecification | ストリームまたはバイトデータを基にした、埋め込みファイル添付記述子 |
FileSpecification.GetData | 埋め込みファイルの生バイト列を取得する |
FileSpecification.Params | 埋め込みファイルのメタデータ(サイズ、チェックサム、日付) |
EmbeddedFileCollection | Document にある FileSpecification 添付ファイルのコレクション |
EmbeddedFileCollection.FindByName | 名前で添付ファイルを検索する |
EmbeddedFileCollection.Delete | 名前で添付ファイルを削除する |
Document.AddEmbeddedFile | 生バイトからファイルを埋め込む便利メソッド |
Document.EmbeddedFiles | ドキュメントの埋め込みファイルコレクション |
Document.HasEmbeddedFiles | ドキュメントに埋め込みファイルが含まれているかどうか |
FileParams | 埋め込みファイルストリームのサイズ/チェックサム/日付メタデータをラップします |