التدفقات ومرفقات الملفات
التدفقات ومرفقات الملفات
تجاوزًا لتجاوزات Document.Open/Document.Save الأساسية، يوفّر Aspose.PDF FOSS لـ .NET لك تحكمًا أدق في كيفية انتقال البايتات داخل وخارج المستند – مخازن قابلة للنمو في الذاكرة للملفات الكبيرة جدًا، و API مخصص لتضمين وفحص واستخراج مرفقات الملفات عبر FileSpecification وEmbeddedFileCollection.
توسيع المخازن في الذاكرة إلى ما يتجاوز 2 جيجابايت
MemoryStream يخزن بياناته في مصفوفة متصلة واحدة، والتي تصل حدها إلى حوالي 2 جيجابايت. 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 جيجابايت –MemoryStreamيطرح استثناءً عندما تصل المصفوفة الخلفية الواحدة إلى هذا الحد. - قم بتحرير كائنات
FileSpecification(وأي تدفق قمت بفتحه يدويًا لها) –FileSpecificationيطبقIDisposable. - تحقق من
Document.HasEmbeddedFilesقبل تكرارEmbeddedFilesلتجاوز تعداد غير ضروري على المستندات التي لا تحتوي على مرفقات. - عيّن
MimeTypeوAFRelationshipعلى كلFileSpecificationحتى يتمكن مستهلكو PDF اللاحقون من تصنيف المرفقات بشكل صحيح. - استخدم
EmbeddedFileCollection.FindByNameللبحث المسماة الفردية بدلاً من كتابة حلقة يدوية.
مشكلات شائعة
| المشكلة | السبب | الإصلاح |
|---|---|---|
OutOfMemoryException حفظ مستند كبير إلى تدفق | MemoryStream محدودة إلى مصفوفة خلفية واحدة بحجم ~2 جيجابايت | احفظ إلى OptimizedMemoryStream بدلاً من ذلك |
FileSpecification.GetData() تُعيد مصفوفة فارغة | لم يتم إعادة تعيين موضع تدفق المصدر قبل إنشاء FileSpecification | قم بتحريك المؤشر في الدفق إلى الموضع 0 (أو أعد فتحه) قبل تمريره إلى FileSpecification |
EmbeddedFiles.FindByName يُرجِع null | اسم المرفق لا يطابق تمامًا (البحث يعتمد على الاسم) | قم بالتكرار على doc.EmbeddedFiles وقارن قيم Name، أو تحقق من Keys |
| حذف المرفق يزيل الإدخال الخطأ | عدة مرفقات تشترك في نفس الاسم | استخدم DeleteByKey مع المفتاح الدقيق من Keys لإزالة غير غامضة |
FAQ
ما الفرق بين MemoryStream و OptimizedMemoryStream؟
MemoryStream يخزن بايته في مصفوفة متصلة واحدة بحجم يقترب من 2 جيجابايت. 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 | البيانات الوصفية (الحجم، المجموع الاختباري، التواريخ) للملف المدمج |
EmbeddedFileCollection | مجموعة من مرفقات FileSpecification على Document |
EmbeddedFileCollection.FindByName | ابحث عن مرفق بالاسم |
EmbeddedFileCollection.Delete | احذف مرفقًا بالاسم |
Document.AddEmbeddedFile | طريقة ملائمة لتضمين ملف من بايتات خام |
Document.EmbeddedFiles | مجموعة الملفات المدمجة في المستند |
Document.HasEmbeddedFiles | ما إذا كان المستند يحتوي على أي ملفات مدمجة |
FileParams | يُغلف بيانات الحجم/المجموع الاختباري/التاريخ لتدفق ملف مضمَّن |