สตรีมและไฟล์แนบ
สตรีมและไฟล์แนบ
นอกเหนือจากการ overload พื้นฐานของ Document.Open/Document.Save แล้ว Aspose.PDF FOSS สำหรับ .NET จะให้การควบคุมที่ละเอียดขึ้นเกี่ยวกับวิธีที่ไบต์เคลื่อนที่เข้าและออกจากเอกสาร – บัฟเฟอร์ในหน่วยความจำที่ขยายได้สำหรับไฟล์ขนาดใหญ่มาก, และ API เฉพาะสำหรับการฝัง, ตรวจสอบ, และสกัดไฟล์แนบผ่าน FileSpecification และ EmbeddedFileCollection.
การขยายบัฟเฟอร์ในหน่วยความจำเกิน 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 สามารถห่อ Stream แทนที่จะบังคับให้คุณต้องบัฟเฟอร์ไฟล์แนบลงใน byte[] ก่อน. สิ่งนี้เป็นประโยชน์เมื่อแหล่งที่มาของไฟล์แนบเป็นสตรีมเอง, เช่น ตัวจัดการไฟล์ที่เปิดอยู่.
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");เคล็ดลับและแนวปฏิบัติที่ดีที่สุด
- ควรเลือกใช้
OptimizedMemoryStreamแทนMemoryStreamเมื่อเอกสารในหน่วยความจำอาจมีขนาดเกิน 2 GB –MemoryStreamจะขว้างข้อยกเว้นเมื่ออาเรย์พื้นฐานเดียวของมันถึงขีดจำกัดนั้น. - ทำลายอินสแตนซ์
FileSpecification(และสตรีมใด ๆ ที่คุณเปิดด้วยตนเองสำหรับพวกมัน) –FileSpecificationimplementsIDisposable. - ตรวจสอบ
Document.HasEmbeddedFilesก่อนทำการวนซ้ำEmbeddedFilesเพื่อข้ามการนับรายการที่ไม่จำเป็นในเอกสารที่ไม่มีไฟล์แนบ. - กำหนด
MimeTypeและAFRelationshipบนแต่ละFileSpecificationเพื่อให้ผู้รับ PDF ด้านล่างสามารถจัดประเภทไฟล์แนบได้อย่างถูกต้อง. - ใช้
EmbeddedFileCollection.FindByNameเพื่อค้นหาชื่อเดียวแทนการเขียนลูปด้วยตนเอง.
ปัญหาทั่วไป
| ปัญหา | สาเหตุ | วิธีแก้ไข |
|---|---|---|
OutOfMemoryException การบันทึกเอกสารขนาดใหญ่ไปยังสตรีม | MemoryStream มีขีดจำกัดที่อาร์เรย์สำรองขนาด ~2GB เพียงหนึ่งอัน | บันทึกไปยัง OptimizedMemoryStream แทน |
FileSpecification.GetData() คืนค่าอาร์เรย์ว่าง | ตำแหน่งของสตรีมต้นทางไม่ได้ถูกรีเซ็ตก่อนที่ FileSpecification จะถูกสร้าง | เลื่อนตำแหน่งสตรีมไปที่ตำแหน่ง 0 (หรือเปิดใหม่) ก่อนส่งให้ FileSpecification |
EmbeddedFiles.FindByName คืนค่า null | ชื่อไฟล์แนบไม่ตรงกันอย่างแม่นยำ (การค้นหาอิงตามชื่อ) | วนซ้ำ doc.EmbeddedFiles แล้วเปรียบเทียบค่า Name, หรือเช็ค Keys |
| การลบไฟล์แนบทำให้ลบรายการผิด | ไฟล์แนบหลายไฟล์ใช้ชื่อเดียวกัน | ใช้ DeleteByKey พร้อมคีย์ที่ตรงจาก Keys เพื่อการลบที่ไม่คลุมเครือ |
FAQ
ความแตกต่างระหว่าง MemoryStream กับ OptimizedMemoryStream คืออะไร?
MemoryStream เก็บไบต์ของมันในอาร์เรย์ต่อเนื่องเดียวที่มีขีดจำกัดประมาณ 2 GB. OptimizedMemoryStream เก็บข้อมูลเป็นชิ้นส่วนขนาดคงที่แทน, ทำให้สามารถขยายเกินขีดจำกัดนั้นได้ – มีประโยชน์สำหรับการดำเนินการ Document.Save ที่ทำทั้งหมดในหน่วยความจำบนไฟล์ขนาดใหญ่มาก.
ฉันสามารถฝังไฟล์โดยไม่ต้องโหลดเข้าเป็น byte[] ก่อนได้หรือไม่?
ได้เลย. FileSpecification(stream, name, description) ยอมรับ Stream โดยตรง, ดังนั้นคุณสามารถฝังจาก File.OpenRead(...) หรือสตรีมอื่นใดโดยไม่ต้องบัฟเฟอร์ลงในหน่วยความจำด้วยตนเอง.
ฉันจะดึงไฟล์ที่ฝังไว้กลับออกจากเอกสารได้อย่างไร?
วนซ้ำ doc.EmbeddedFiles แล้วเรียก GetData() บนแต่ละ FileSpecification เพื่อดึงข้อมูลไบต์ดิบออกมา.
เมธอด EmbeddedFileCollection.Delete(name) จะลบไฟล์แนบทั้งหมดที่มีชื่อนั้นหรือไม่?
ไม่ – ให้กำหนดไฟล์แนบเดียวอย่างแม่นยำด้วย DeleteByKey และคีย์เฉพาะจาก Keys หากมีไฟล์แนบหลายไฟล์ที่ใช้ชื่อเดียวกัน.
FileSpecification สามารถนำกลับมาใช้ซ้ำได้อย่างปลอดภัยในหลายเอกสารหรือไม่?
ไม่. FileSpecification ทำงานตาม IDisposable และห่อหุ้มสตรีมไฟล์ที่ฝังเพียงหนึ่งไฟล์; ควรสร้างอินสแตนซ์ใหม่สำหรับแต่ละไฟล์แนบในแต่ละเอกสาร.
API Reference สรุป
| คลาส / เมธอด | คำอธิบาย |
|---|---|
OptimizedMemoryStream | สตรีมในหน่วยความจำที่ขยายได้ซึ่งเกินขีดจำกัด 2GB ของ MemoryStream |
OptimizedMemoryStream.Write | เขียนไบต์ลงในบัฟเฟอร์ |
OptimizedMemoryStream.ToArray | คืนค่าไบต์ที่บัฟเฟอร์เป็นอาร์เรย์ไบต์ |
FileSpecification | ตัวบรรยายไฟล์แนบที่ฝังอยู่, รองรับโดยสตรีมหรือข้อมูลไบต์ |
FileSpecification.GetData | ดึงไบต์ดิบของไฟล์ที่ฝังไว้ |
FileSpecification.Params | ข้อมูลเมตา (ขนาด, checksum, วันที่) ของไฟล์ที่ฝังไว้ |
EmbeddedFileCollection | คอลเลกชันของ FileSpecification ไฟล์แนบบน Document |
EmbeddedFileCollection.FindByName | ค้นหาไฟล์แนบโดยใช้ชื่อ |
EmbeddedFileCollection.Delete | ลบไฟล์แนบตามชื่อ |
Document.AddEmbeddedFile | เมธอดสะดวกสำหรับฝังไฟล์จากไบต์ดิบ |
Document.EmbeddedFiles | คอลเลกชันไฟล์ฝังในเอกสาร |
Document.HasEmbeddedFiles | ว่าเอกสารมีไฟล์ฝังอยู่หรือไม่ |
FileParams | ห่อหุ้มข้อมูลเมตาขนาด/เช็คซัม/วันที่ สำหรับสตรีมไฟล์ที่ฝังอยู่ |