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

تضمين الملفات ذات أنواع مختلفة في ملف واحد

مغلق
بدأه دريد عبد الله في 3 يناير 2008 · 20 رد · 3,191 مشاهدة · في لغة Ms Visual Basic 6 وما قبلها من إصدارات
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

مرحبا

لدي سؤال أو بالأحرى طلب

لو سمحتم:

كيف يمكنني أن أخزن ملف صورة مثلا أو ملف صوت أو...مع نص في ملف نصي

مثلا: فلنفترض أنه لدينا ملف نصي,يحتوي كلمات أو أرقام..ولدينا ملف صورة,ونريد

أن نخزنهما في ملف واحد: يحتوي هذا الملف على الملف النصي أولا ثم على الصورة

كيف يمكنني أن أخزنهما في نفس الملف,وكيف يمكنني أن أفصلهما عن بعضهما مجددا.

حاولت تخزين النص في ملف ثم بعده أخزن الصورة في نفس الملف وذلك عن طريق استخدام أوامر فتح

الملفات و القراءة منها والطباعة فيها,بحيث أني نقلت ملف الصورة كمستند نصي(يحتوي رموز طبعا) إلى الملف الذي أريد تخزينها فيه

لكني عندما استخرجتها من الملف لم تفتح .

لا تؤاخذوني على هذه الطلبات الغير مألوفة كثيراً.

وشكرا

Doried Abd Allah

Prelware D&D Association

Lattakia/Syria

#2

الفكرة فى انك ستصنع نوع ملف جديد بأنك ستصنع نوعين من الـ Headers أولهما بحتوى على عدد الملفات الموجوده فى ذلك الملف و ايضا يحتوى على بيانات اخرى خاصة بذلك الملف مثل الإمتداد او الإصدار و هكذا أما الـ Header الثانى فهو خاص بالملفات التى سيتم دمجها و سيتم وضع عدد من ذلك الـ Header مساوى لعدد الملفات التى سيتم دمجها بمعنى انك هتدمج ملفين فى ملف واحد يبقى هيبقى فيه Main Header فى اول الملف و أيضا فيه 2 Header خاصين بالملفين، هذا الـ Sub Header بيحتوى على مجموعة من البيانات مثل أسم الملف و إمتداده حجمه و بداية موقعه داخل ملفك و ما إلى ذلك.

التالى وصف برمجى للكلام السابق عسى ان يزيل عنه بعض الغموض

Type tMainHeader  ' Size 8 bytes
	Ext as string * 3			  ' take 3 bytes
	Version as String *3		' take 3 bytes
	NumofFiles as integer   'take 2 bytes
End Type


Type tFileHeader ' take 28 byte
	FileName	  as string * 20   ' take 20 byte
	FileSize		as long			 ' take 4 bytes
	Offset   as long					 ' take 4 bytes
End Type

السابق هو شكل الـ Header الذى سيمثل ملفاتك برمجيا

التالى هو إستخدامه و بفرض اننا سنخزن ملفين معاً داخل ملف جديد سيأخذ الإسم "new.dat" و سيتم حفظه داخل C

Private Sub Command1_Click()
Dim MainHeader As tMainHeader  ' main file header
Dim FileHeader(1) As tFileHeader  ' header for 2 files

MainHeader.Ext = "DAT"
MainHeader.Verson = "1.0"
MainHeader.NumofFiles = 2


Dim Arr1() As Byte  ' for holding 1st file data
Dim Arr2() As Byte  ' for holding 2nd file data

Open "C:\FirstFile.mp3" For Binary Access Read Lock Read Write As #1
FileHeader(0).FileName = "FirstFile.mp3"
FileHeader(0).FileSize = LOF(1)

ReDim Arr1(FileHeader(0).FileSize - 1)

Get #1, , Arr1
Close #1

Open "C:\SecondFile.png" For Binary Access Read Lock Read Write As #1
FileHeader(1).FileName = "SecondFile.png"
FileHeader(1).FileSize = LOF(1)

ReDim Arr2(FileHeader(1).FileSize - 1)

Get #1, , Arr2
Close #1


Open "c:\new.dat" For Binary Access Write Lock Read Write As #1
Put #1, , MainHeader

FileHeader(0).Offset = 8 + 28 * 2
FileHeader(1).Offset = FileHeader(0).Offset + FileHeader(0).FileSize

Put #1, , FileHeader

Put #1, , Arr1
Put #1, , Arr2

Close #1


Debug.Print 8 + 28 * 2 + FileHeader(0).FileSize + FileHeader(1).FileSize


End Sub

شرح الكود السابق خطوة بخطوة

الكود السابق كل ما يفعله هو دمج الملفين FirstFile.mp3 و SecondFile.png داخل ملف جديد اسمه New.dat ومكان المفين داخل الـ C و الملف الجديد يتم إنشائه داخل الـ C أيضا.

اولا صنعت متغير يمثل الـ Header الرئيسى للملف New.dat وبعد ذلك صنعت متغير عبارة عن مصفوفة تحتوى على عنصرين و هى تمثل الـ Header الخاص بالملفين اللذان سيتم دمجهما سويا.

بعد ذلك وضعت البيانات الخاصه بالـ MainHeader و هى الإمتداد و إصدار الملف و عدد الملفات بداخله و هذا العدد سيفيدنا فى حال اننا لا نعرف عدد الملفات الموجوده و سيفيدنا فى استخراج الملفات بشكل صحيح كما سترى لاحقا.

بعد ذلك صنعت مصفوفتين هما Arr1 و Arr2 و سيحتووا على بيانات الملفين - لا تحاول استخدام هذه الطريقه مع الملفات الكبيرة - و بعد ذلك قمت بفتح الملف الأول بنمط القراءة فقط لى و منع اى برنامج اخر من الكتابه فيه ثم كتبت بياناته داخل الـ Header الخاص به و هى اسمه و مساحته، و عرفت مساحته بإستخدام الدالة LOF و اعطيت لها رقم الملف المفتوح و هو 1 فأحضرت لى مساحته ثم اعدت تحجيم الصفوفة Arr1 لحجم الملف ثم طرحت منه واحد لإن الترقيم فى المصفوفة يبدأ من 0 و ليس 1 و بعد ذلك و ضعت بيانات الملف فى المصفوفة ثم اغلقت الملف.

بعد ذلك كررت نفس العمليه مع الملف الثانى - قد تفضل و ضعها داخل Function حتى لا تعيد كتابة الكود العديد من المرات.

نأتى الأن لأهم خطوة و هى صنع الملف الجديد قمت بفتح الملف الجديد داخل الـ C بنمط الكتابه فقط و منع اى برامج أخرى من القراءه او الكتابه فيه بعد ذلك قمت بوضع الـ MainHeader ثم بدأت بحساب موقع الملفين داخل الملف الجديد قبل وضعهم و كتبت فى الـ offset الخاص بالملف الأول الرقم التالى 8 + 28*2. الرقم 8 هو مساحة الـ MainHeader و الرقم 28 * 2 هو مساحة الـ Headers الخاصة بالملفين و بالتالى فإن بداية موقع الملف الأول تكون بعد الـ MainHeader و الـ FileHeaders، بعد ذلك قمت بجعل الـ Offset الخاص بالملف الثانى يساوى الـ Offset الخاص بالملف الأول يالإضافة إلى حجم الملف الأول و بالتالى موقع الملف الثانى داخل الملف الجديد سيكون بعد الـ Headers و أيضا بعد الملف الأول بعد ذلك قمت بوضع قيم المصفوفتين داخل الملف الجديد ثم أمرت البرنامج بطباعة مساحة الملف الجديد داخل شاشة الـ Immediate Window، بعد ذلك أغلقت الملف الجديد.

ناتى للخطوة التالية و هى إعادة فك الملفين من الملف New.dat و الكود الخاص بهما كالتالى:

Private Sub Command2_Click()

Dim MainHeader As tMainHeader  ' main file header
Dim FileHeader() As tFileHeader  ' header for 2 files
Dim Arr1() As Byte
Dim Arr2() As Byte

Open "c:\new.dat" For Binary As #1
Get #1, , MainHeader

ReDim FileHeader(MainHeader.NumofFiles - 1)

Get #1, , FileHeader

ReDim Arr1(FileHeader(0).FileSize - 1)
ReDim Arr2(FileHeader(1).FileSize - 1)

Get #1, , Arr1
Get #1, , Arr2

Close #1


Open "c:\" & FileHeader(0).FileName For Binary As #1
Put #1, , Arr1
Close #1


Open "c:\" & FileHeader(1).FileName For Binary As #1
Put #1, , Arr2
Close #1

End Sub

شرح الكود السابق

أولا عملت متغير يمثل الـ tMainHeader و بعدها صنعت مصفوفة غير محددة الأبعاد و تمثل FileHeader، بعد ذلك صرحت عن متغيريين هما Arr1 و Arr2 و هما سيحتووا على بيانات الملفين.

بعد ذلك قمت بفتح الملف new.dat و قمت بأخذ بيانات منه و وضعتها داخل المتغيرMainHeader، السؤال الأن كم عدد البايتات التى سيتم وضعها داخل المتغير MainHeader؟ و الإجابة هى لهذا المتغير مساحة و هى 8 بايت و هى نفس المساحة التى سيتم وضعها فيه، بعد ذلك قمت بإعادة تحجيم المصفوفة FileHeader و جعلت عدد العناصر بها مساوى لـ MainHeader.NumofFiles -1 و ذلك لإن ترقيم المصفوفة يبدأ من صفر.

بعدها اخذت بيانات من الملف new.dat و وضعتها داخل المصفوفة FileHeader و حيث ان المصفوفة بها عنصرين فقط كل واحد منهم مساحته 28 لذا سيتم اخذ اول 28 بايت من بعد الـ MainHeader و وضعهم داخل العنصر الأول بالمصفوفة يليه 28 بايت للعنصر الثانى.

قمت بعدها بإعادة تحجيم المصفوفتين Arr1 و Arr2 بحجم الملفين الموجود بياناتهم داخل الـ FileHeader و ايضا انقصت منهم 1 لإن ترقيم المصفوفة يبدأ من صفر و ليس واحد، بعد ذلك قمت بفتح مفلين داخل الـ C وأسمهما مماثل للإسمين الموجودين داخل الـ FileHeader.

اتمنى ان يكون الشرح بسيط و سهل

هذا هو البرنامج الذى قمنا بصنعه لا تنسى وضع ملفين داخل الـ C بالأسماء المذكورة سابقا.

Splliter.rar

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#3

الاخ game

هل استطيع دمج اكثر من 100 ملف دفعة واحدة

وكيف استعيد ملف واحد فقط في كل مرة

واعرضة في TextBOX بدلا من فك الملفات

ولك تحياتي

#4
awajihm كتب:
هل استطيع دمج اكثر من 100 ملف دفعة واحدة

نعم تستطيع دمج عدد لا نهائى من الملفات فى ملف واحد، و لكن ستحتاج لإعادة هيكلة الكود مرة اخرى لإن الكود السابق يتعامل مع ملفين فقط

awajihm كتب:
وكيف استعيد ملف واحد فقط في كل مرة

واعرضة في TextBOX بدلا من فك الملفات

تستطيع ذلك عن طريق معرفة الـ offset الخاص بالملف الذى تريد فكه فقط.

و عموما سأقوم بعمل درس أشرح فيه طريقة تضمين عدة ملفات بملف واحد و التعامل معه بعدة طرق و لكن بعد إنتهائى من درس الـ Trainer

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Game Expert في 5 يناير 2008 في 15:27

مدونتي: C++ Tips and Tricks

#5

أشكرك جزيلا جزيلا يا أخي الكريم.

أنا حاولت أن أتبع نفس الطريقة لكني أهملت بعض القواعد كما أني كنت أقوم بفتح الملفين بالطريقة التسلسلية ليس بالثنائية.

شكرا جزيلا مجددا..!

أتمنى لك التوفيق والإستفادة من خبراتك لتحقيق أمنياتك.

Doried Abd Allah

Prelware D&D Association

Lattakia/Syria

#6

جزالك الله خيرا يا اخي على هذه الافاده

شكوت الى وكيع سوء حفظي فأشار على بترك المعاصي واخبرني ان علم الله نور و نور الله لا يأتي لعاصي

#7

لو سمحتوا يا اخوان عندي سؤال بسيط

اقتباس
ثم بدأت بحساب موقع الملفين داخل الملف الجديد قبل وضعهم و كتبت فى الـ offset الخاص بالملف الأول الرقم التالى 8 + 28*2. الرقم 8 هو مساحة الـ MainHeader و الرقم 28 * 2 هو مساحة الـ Headers الخاصة بالملفين
هي عندما انك ضربت في 2 * 28 انك قد حسبت مساحة header for the 2 files ليس لاول ملف

ثم جمعت اوفست للملف التاني

سؤال أخر اذا اردت ان ادمج ملف ذو حجم كير او اكثر من ملف كيف؟

و شكرا لكم و يسلمواا ايديكم على الموضوع................

شكوت الى وكيع سوء حفظي فأشار على بترك المعاصي واخبرني ان علم الله نور و نور الله لا يأتي لعاصي

#8

مرحبا مجددا

سأقدم لكم الآن البرنامج وقد عدلته وهو يستند على نفس المبدأ الذي قدمه الأخ

لكن هذا البرنامج يستطيع أن يضمن عدد لانهائي من الملفات في ملف واحد,وليس فيه الكثير من التعقيد Game Expert

هذا البرنامج موجود داخل الملف التالي:

Compacting.rar

كل ما عليك هو تحديد الملفات ثم النقر على الزر"انتهيت من تحديد الملفات" ثم تستطيع فكها.

طبعا هذا البرنامج أشبه ببرامج الأرشفة التي تجمع الملفات تضغطها ,لكن هذا البرنامج يحافظ على حجم الملفات ولا يضغطها

أنا كنت بحاجة الفكرة لأن أحد البرامج التي صنعتها كان يولد ملفات و يستخدم الخلفيات,فكنت محتاجا إلى تضمين صور الخلفيات ضمن الملفات التي يولدها البرنامج,بدون

أن أربطها به ربط.

وجزيل الشكر للأخ Game Expert

الذي ساعدني في حل مشكلاتي في هذا المجال..!

Doried Abd Allah

Prelware D&D Association

Lattakia/Syria

#9
اقتباس
هي عندما انك ضربت في 2 * 28 انك قد حسبت مساحة header for the 2 files ليس لاول ملف ثم جمعت اوفست للملف التاني

يحتوى الملف الناتج من عملية الدمج على ما يلى:

1. الـ MainHeader.

2. الـ FileHeader للملف الأول.

3. الـ FileHeader للملف الثانى.

4. بيانات الملف الأول.

5. بيانات الملف الثانى.

موقع بداية بيانات الملف الأول offset تساوى المساحة التى يوضع فيها الخطوات من 1 إلى 3

موقع بداية بيانات الملف الثانى offset تساوى المساحة التى يوضع فيها الخطوات من 1 إلى 3 بالإضافة لمساحة بيانات الملف الأول (الخطوة الرابعة)

و كما ترى فإن الخطوات من 1 إلى 3 كررت فى عملية حفظ الـ offset للملفين لذا فالـ offset للملف الثانى يمكن كتابته على الصورة التاليه:

موقع بداية بيانات الملف الثانى offset تساوى الـ offset للملف الأول + مساحة بيانات الملف الأول

و الرقم 28 ضربته فى الرقم 2 لإنه يوجد Two Headers للملفين و لهما مساحة واحدة.

اقتباس
سؤال أخر اذا اردت ان ادمج ملف ذو حجم كير او اكثر من ملف كيف؟

عملية دمج ملف او اكثر ذوات احجام كبيرة تتم بنفس الطريقة السابقة مع بعض التعديلات وهى انك لن تقوم بعمل مصفوفة و وضع البيانات فيها لإن مع الملفات الكبيرة انت تقوم بتضييع مساحات من الذاكرة بدون دتعى و لكن ما يحدث فى تلك الحالة هو انك تقوم بعمل Pipe بين ملفك الحاوى و الملف الذى تريد تضمينه و بالتالى فلن نحتاج لعمل مصفوفة.

الـ pipe يمكن صنعها بالعديد من الطرق أسهلها إستخدام الـ Stream Class الموجوده داخل مكتبة الـ ADO 2.8 و لا تنسى ان تجعل الـ Type بها adTypeBinary حتى يتسنى لك التعامل مع الملف Binary.

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#10

كيف اعرض بيانات نلف واجد فقط في لست

او في الفورم

#11

مش فاهم قصدك ياريت توضح اكتر

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#12

قصدي بعد دمج مثلا 7 ملفات في ملف

هل استطيع عرض بيانات الملف الخامس من الملف الجديد مثلا في في اداة

ListBOX كما في الملف الاساسي

ولك تحياتي

#13

طبعا ممكن انت مش عندك موقع الملف الخامس و مساحته انت ممكن تعمل حاجه زى الكود ده

Dim St as string
St=String(FileHeader(4).FileSize,Chr$(0))

Get #1,FileHeader(4).StartOffset,St

شرح الكود السابق

انا بفترض انك فتحت الملف و حملت بيانات الـ Headers جوا المصفوفة FileHeader و الملف اللى انت عايز تاخد البيانات منه و تحطها فى لست بوكس او حتى تكست بوكس موجوده فى الـ Index الرابع للمصفوفة، و حيث ان البيانات نصية لذا فلا داعى لتصنيع مصفوفة من نوع Byte ولكن هنا صنعت متغير نصى و بعد ذلك استخدمت الدالة String و قلت له املء المتغير St بعدد الـ FileSize للملف FileHeader 4 و الحرف الذى تضعه فى المتغير هو Chr 0 و هى تماثل Null Charchter.

العملية السابقة تماثل تماما إنشائك لمتغير نصى ذو حجم ثابت، بمعنى الكود التالى

Dim St as string
St=String(FileHeader(4).FileSize,Chr$(0))

يساوى الكود التالى

Dim St as String * FileHeader(4).FileSize

و حيث انه اذا قمت بكتابة الكود السابق سيعترض المترجم فكان لا مفر من استخدم الطريقة الأولى

بعد ذلك كتبت الكود التالى

Get #1,FileHeader(4).StartOffset,St

و هو لإحضار بيانات الملف الخامس من الملف الموجود بالهارد ديسك و وضعه فى المتغير St و حيث ان هذا المتغير له مساحه تماثل مساحة المف الذى سنضعه فيه فسيقوم اليجوال بيسك بملء المتغير ببيانات الملف الخامس فقط.

لديك الأن بيانات الملف الخامس و بالتالى تستطيع التعامل مع المتغير St كما يحلو لك

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Game Expert في 12 يناير 2008 في 03:59

مدونتي: C++ Tips and Tricks

#14

عفوا ياعزيزي

لم افهم شيا ولم يعمل الكود معي

ويعطي خطا في FileHeader

#15

اقرا الموضوع من اوله و انت تعرف تنفذ الكود

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#16

شكر يا اخي Game Expert قد أزلت بعض الغموض جزاك الله خيرا ....

تم تعديل هذه المشاركة بواسطة RbcandWbc في 12 يناير 2008 في 15:24

شكوت الى وكيع سوء حفظي فأشار على بترك المعاصي واخبرني ان علم الله نور و نور الله لا يأتي لعاصي

#17

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

بصراحة انا مبتدي

الرجاء المساعدة في الكود

ولك تحياتي

#18

سأضع لك مثال تطبيقى بعد قليل

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#19

انا في الانتظار

وشكرا علي التواصل

#20

لقد صنعت المثال و هو التالى

Desktop.rar

يحتوى الملف المضغوط على فولدرين هما Combin و Load

المشروع Combin يقوم بدمج 3 ملفات نصية - موجودين فى نفس الفولدر - فى ملف واحد سيتم وضعه فى نفس الفولدر.

المشروع Load يقوم بإظهار احد الملفات النصية التى تم دمجها فى الملف الجديد داخل الـ Textbox مباشرة دون الحاجه لعمل ملف جديد.

التالى ScreenShot للبرنامج

post-135620-1200190022_thumb.jpg

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#21

موضوع اكثر من رائع جزاكم الله خيرا

قولو لا اله الا الله تفلحو

هذا الموضوع مغلق.

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

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

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

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

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