Aliran dan Lampiran File
Aliran dan Lampiran File
Di luar overload dasar Document.Open/Document.Save, Aspose.PDF FOSS untuk .NET memberi Anda kontrol yang lebih halus atas cara byte bergerak masuk dan keluar dokumen – buffer dalam memori yang dapat tumbuh untuk file yang sangat besar, dan API khusus untuk menyematkan, memeriksa, dan mengekstrak lampiran file melalui FileSpecification dan EmbeddedFileCollection.
Memperbesar Buffer Dalam Memori Melebihi 2 GB
MemoryStream menyimpan datanya dalam satu array berkelanjutan, yang dibatasi sekitar 2 GB. OptimizedMemoryStream menyimpan data dalam potongan berukuran tetap sebagai gantinya, sehingga dapat menampung dokumen yang jauh lebih besar ketika Anda menyimpan atau membangun PDF sepenuhnya dalam memori.
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}");Anda juga dapat menulis langsung ke dalamnya, dengan cara yang sama seperti yang Anda lakukan dengan Stream mana pun:
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);Menyematkan file langsung dari aliran
FileSpecification dapat membungkus Stream alih-alih mengharuskan Anda menampung lampiran ke dalam byte[] terlebih dahulu. Ini berguna ketika sumber lampiran itu sendiri merupakan aliran, seperti handle file yang terbuka.
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");Menyematkan file dari byte mentah
Document.AddEmbeddedFile adalah metode yang memudahkan untuk menyematkan file langsung dari array byte, tanpa membangun FileSpecification secara langsung.
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");Menenumerasi dan mengekstrak file yang disematkan
Document.EmbeddedFiles adalah EmbeddedFileCollection yang dapat Anda enumerasi. Setiap entri adalah FileSpecification, dan GetData() mengembalikan byte mentah dari lampiran.
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);
}
}Menemukan, memeriksa, dan menghapus lampiran
Gunakan FindByName untuk mencari satu lampiran, Params untuk membaca metadata-nya, dan Delete/DeleteByKey untuk menghapusnya.
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");Tips dan Praktik Terbaik
- Lebih pilih
OptimizedMemoryStreamdaripadaMemoryStreamsetiap kali dokumen dalam memori mungkin melebihi 2 GB –MemoryStreamakan melempar kesalahan begitu array pendukung tunggalnya mencapai batas tersebut. - Buang instance
FileSpecification(dan aliran apa pun yang Anda buka secara manual untuk mereka) –FileSpecificationmengimplementasikanIDisposable. - Periksa
Document.HasEmbeddedFilessebelum mengiterasiEmbeddedFilesuntuk melewati enumerasi yang tidak perlu pada dokumen tanpa lampiran. - Tetapkan
MimeTypedanAFRelationshippada setiapFileSpecificationsehingga konsumen PDF hilir dapat mengklasifikasikan lampiran dengan benar. - Gunakan
EmbeddedFileCollection.FindByNameuntuk pencarian bernama tunggal alih-alih menulis loop manual.
Masalah Umum
| Masalah | Penyebab | Perbaikan |
|---|---|---|
OutOfMemoryException menyimpan dokumen besar ke stream | MemoryStream terbatas pada satu array pendukung ~2GB | Simpan ke OptimizedMemoryStream sebagai gantinya |
FileSpecification.GetData() mengembalikan array kosong | Posisi stream sumber tidak direset sebelum FileSpecification dibuat | Pindahkan aliran ke posisi 0 (atau buka kembali) sebelum mengirimkannya ke FileSpecification |
EmbeddedFiles.FindByName mengembalikan null | Nama lampiran tidak cocok secara persis (pencarian berdasarkan nama) | Iterasi doc.EmbeddedFiles dan bandingkan nilai Name, atau periksa Keys |
| Menghapus lampiran menghapus entri yang salah | Beberapa lampiran memiliki nama yang sama | Gunakan DeleteByKey dengan kunci tepat dari Keys untuk penghapusan yang tidak ambigu |
FAQ
Apa perbedaan antara MemoryStream dan OptimizedMemoryStream?
MemoryStream menyimpan baitnya dalam satu array berkelanjutan yang dibatasi sekitar 2 GB. OptimizedMemoryStream menyimpan data dalam potongan berukuran tetap, sehingga dapat tumbuh melewati batas tersebut – berguna untuk operasi Document.Save yang dilakukan sepenuhnya di memori pada file yang sangat besar.
Apakah saya dapat menyematkan file tanpa memuatnya ke dalam byte[] terlebih dahulu?
Ya. FileSpecification(stream, name, description) menerima Stream secara langsung, jadi Anda dapat menyematkan dari File.OpenRead(...) atau aliran lain apa pun tanpa menyangga ke memori sendiri.
Bagaimana cara saya mengambil file yang disematkan kembali dari dokumen?
Iterasi doc.EmbeddedFiles dan panggil GetData() pada setiap FileSpecification untuk mendapatkan byte mentah.
Apakah EmbeddedFileCollection.Delete(name) menghapus setiap lampiran dengan nama itu?
Tidak — targetkan satu lampiran secara tepat dengan DeleteByKey dan kunci spesifik dari Keys jika beberapa lampiran memiliki nama yang sama.
Apakah FileSpecification aman untuk digunakan kembali di beberapa dokumen?
Tidak. FileSpecification mengimplementasikan IDisposable dan membungkus satu aliran file yang disematkan; buat instance baru untuk setiap lampiran per dokumen.
API Reference Ringkasan
| Kelas / Metode | Deskripsi |
|---|---|
OptimizedMemoryStream | Aliran memori yang dapat tumbuh yang melampaui batas 2GB dari MemoryStream |
OptimizedMemoryStream.Write | Menulis byte ke dalam buffer |
OptimizedMemoryStream.ToArray | Kembalikan byte yang di-buffer sebagai array byte |
FileSpecification | Deskriptor lampiran file tersemat, didukung oleh aliran atau data byte |
FileSpecification.GetData | Ambil byte mentah dari file tersemat |
FileSpecification.Params | Metadata (ukuran, checksum, tanggal) untuk file tersemat |
EmbeddedFileCollection | Koleksi lampiran FileSpecification pada Document |
EmbeddedFileCollection.FindByName | Cari lampiran berdasarkan nama |
EmbeddedFileCollection.Delete | Hapus lampiran berdasarkan nama |
Document.AddEmbeddedFile | Metode praktis untuk menyematkan file dari byte mentah |
Document.EmbeddedFiles | Koleksi file yang disematkan dalam dokumen |
Document.HasEmbeddedFiles | Apakah dokumen berisi file yang disematkan apa pun |
FileParams | Membungkus metadata ukuran/checksum/tanggal untuk aliran file tersemat |