الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

[سؤال]كيفية وضع محتوى ملف كاملا في متغير أو في جدول؟

بدأه djug في 11 مايو 2009 · 11 رد · 879 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

في برنامج أقوم بكتابته أحتاج إلى وضع محتوى ملف في متغير أو جدول ليقوم البرنامج بالتعامل معه

فكرت في أن أضع محتوى الملف في جدول للـ byte لكن لاحظت أنه لدى إنشاء جدول و تحديد طول الجدول فإن هذا الطول يجب أن يكون int و لا يمكن أن يكون long

و بالتالي فإن الملفات التي يمكن التعامل معها ستكون صغيرة

و بالتالي يجب إيحاد حل آخر (فكرت أيضا في جدول من الشكل byte[][1024]

هناك مشكل آخر و هو أن حجم المتغير أو الجدول المستعمل (في الذاكرة) يجب أن يكون مساويا لحجم الملف بدقة (لا وجود لأية زيادة و لو byte واحد)

هل من اقتراحات أو أفكار؟

#2

وعليكــم السـلام ورحمة الله وبركاتـه..

اخى الكريم - افهم من سؤالك انك تريد تحميل الملف الى مصفوفة من البايتات. الحل ممكن لكن فقط مشكلته ان كان الملف حجمه كبير مثل واحد جيجا مثلا فى هذه الحالة ممكن ان تضطر الى استخدام Memory-mapped files. فى هذه الحالة استخدام MappedByteBuffer الحل الامثل و هى تتوارث من ByteBuffer.

الكود 1: تحميل الملف الى مصفوفة بايت

File file = new File("filename");
URL url = null;
try {
	  url = file.toURL();
	  URLConnection u = url.openConnection();
	  int size 		= u.getContentLength();	
	  byte[] array 	= new byte[size];
	  int bytes_read 	= 0;

	  DataInputStream  in = new DataInputStream(u.getInputStream());
	  while(bytes_read < size){	
	bytes_read += in.read(array, bytes_read, size - bytes_read);
	  }

for(int i = 0; i < size; i++)
	  System.out.print((char)bytes_read);

	  in.close();
} catch (MalformedURLException e) {
}

الكود 2 : استخدام MemoryByteBuffer فى حالة التعامل مع الملفات الكبيرة

File file = new File("filename");
FileChannel fc = new RandomAccessFile(file).getChannel();
int size = fc.size();	
MappedByteBuffer mb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
for(int i = 0; i < size; i++)
	  System.out.print((char)mb.get(i));
fc.close();

والسلام ختام

تم تعديل هذه المشاركة بواسطة Ahmedvc في 11 مايو 2009 في 15:38

#3

شكرا جزيلا لك

سأجرب و لي رجعة إن شاء الله

بخصوص حجم الملف فهو لا يتعدى بضع MB

بارك الله فيك

#4

ممممممممممممممم

على حسب علمي أن الفئة MappedByteBuffer تستخدم المصفوفا في هيكليتها

لذا لا أعرف أن كانت تحل المشكلة أصلاً

(لو كانت معلوماتي خاطئة أرجو تصويبي)

ربما لو استبدلت موضوع المصفوفة بالحلقات المتسلسلة Linked List ستحصل على نتيجة جيدة

على أية حال موضوع أن المصفوفات محدودة بطول int ليس بالشيء السيء

فأنت تستطيع حجز مصفوفة طولها 2147483647

مما يعني أنك تستطيع تخزين بيانات إلى حد 2047 ميغابايت

تقريباً 2 جيجا بايت

بأمانة لو لم تكن تعمل في مجال يحتاج أحجام كبيرة جداً جداً ستبدأ المشاكل

لكن في الوضع العادي ربما لن تكفي الذاكرة لمصفوفة بهذا الحجم

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#5

كلامك صحيح تماما اخى - لكن لاحظ انت المتحكم فى عمل Memory Page بحيث لاتتخطى الحد المطلوب من خلال دالة map مثلا صفحة لكل 500 ميجا. استخدام دالة map و unmap مستحب فى التعامل مع الملفات الكبيرة لاسباب عديده حيث ان دالة map تقوم بانشاء virtual memory space للملف و تقوم بلف (wrap) الميمورى بافر بمحتوياتها. لذا صحيح هى مصفوفة ذاكرة لكنها ليست Normal Java Heap لذا عند استدعاء دالة get تقوم باحضار القيمة من المف مباشره و تعكس اى تغير لمحتويات الملف و العكس صحيح لدالة put. و ايضا ادارة الذاكرة الظاهرية هى ملقاه على النظام و لاتدخل من JVM فيها. لو استخدمت مصفوفة بايت لملف مساحته واحد جيجا سيكون هناك Performance Degradation تدهور واضح فى الاداء و استخدام الحلقات المتسلسلة Linked List ليس الحل المثالى بالتأكيد فمازلت تتعامل فى نطاق JVM Heap و تملئ الذاكرة بمحتويات ملف كبير للغاية.

والسلام ختام

#6
   File f = new File("C:\\client.exe");
   byte[] b = new byte[(int)f.length()];

و هيك بتكون حملت الملف كاملا داخل مصفوفة البايتات اللي اسمها b

تم تعديل هذه المشاركة بواسطة mofeed chaar في 12 مايو 2009 في 07:36

mofeedchaar@hotmail.com

#7

أخ Ahmedvc

هل ممكن تشرح أكثر عن مفهوم MappedByteBuffer

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#8

أخ Ahmedvc

هل ممكن تشرح أكثر عن مفهوم MappedByteBuffer ؟

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#9

السلام عليكــم ورحمـة الله وبركاتــه ،،

هذا المقال يشرحها قليلا،

http://java.sun.com/developer/technicalArt...s/releases/nio/

رغم أنه قديم ولكن أظنه مازال صالحا

وهذا مقال آخر يتكلم أيضا عن nio

http://www.panix.com/~mito/articles/articl...o/j-nio-ltr.pdf

تم تعديل هذه المشاركة بواسطة herch في 12 مايو 2009 في 12:29

#10

بارك الله فيكم أجمعين

الملفات المستعملة ليست بالحجم الكبير جدا

أنا عن الـ linked list فلا تفي بالغرض

لأن البرنامج الذي أقوم بكتابته عبارة عن Jade Agent يحمل معه ملفات

و عليه يجب أن يكون الملف داخل متغير في الـعميل و ليس فقط في الذاكرة لأنه لدى انتقاله من node إلى آخر لا يمكنه نقل حجوزات الذاكرة ما لم تكن متغيرات

تم حل المشكل

بارك الله في الجميع

بارك الله فيكم أجمعين

الملفات المستعملة ليست بالحجم الكبير جدا

أنا عن الـ linked list فلا تفي بالغرض

لأن البرنامج الذي أقوم بكتابته عبارة عن Jade Agent يحمل معه ملفات

و عليه يجب أن يكون الملف داخل متغير في الـعميل و ليس فقط في الذاكرة لأنه لدى انتقاله من node إلى آخر لا يمكنه نقل حجوزات الذاكرة ما لم تكن متغيرات

تم حل المشكل

بارك الله في الجميع

#11

أعتذر اخى عن التأخر فى الرد - ان شاء سأكتب رد تفصيلى اكثر غدا - لكن حتى ذلك الوقت اليك هذا الرابط من جوجل بوك و هو جزء من كتاب Java NIO - O'REILLY يتكلم بتفصيل عن Memory-mapped files.

روابط متعلقة بالرد:

Java NIO Book :

http://books.google.ca/books?id=BSz14O3uQw...80&lpg=PA80

#12

شكراً لكم herch و Ahmedvc

اقرأ حالياً عن nio وأحاول التعمق فيها بقدر المستطاع

في أقرب فرصة سأقوم بقراءة المقالات التي وضعتموها

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…