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

مشروع برنامج لتقسيم ودمج الملفات (للمبتدئين)

رائج
بدأه Wajdy Essam في 1 أغسطس 2009 · 50 رد · 8,826 مشاهدة · في مشاريع ومسابقات القسم
مشاركة: واتساب X فيسبوك تيليجرام
#26

أقوم حاليا , بعمل تجارب .. وقفت عند النقطة التي ذكرها الاخ وجدي :

اقتباس
قرائه الملفات الكبيره جدا ..

حيث أقصى ماأمكنني قراءته , هو ملف ذو حجم 4 جيجا ( لم أطبق ذلك عمليا .. لكن أستخدم النوع unsigned int ) .. ولكن هل أنظمة التشغيل الحالية تدعم أكبر من هذا الحجم :-) .. لم أبحث كثيراً بصراحة .. ولا أعلم الى أين وصل الحجم الأقصى حتى الان .

اقتباس
النقطه 3 حليتها في محاولتي وأيضا أظن محاولة الأخ أمين وأي شخص سيلجأ لهذا الحل وهو بقرائه أجزاء صغيره من الملف Small Chunks وليس بقرائه الملف بالكامل ، أي سنقوم نقرأ مثلا من الملف 1GB حوالي 10 ميغا ثم نقوم بكتابتها في الملف الأول ، ونقرأ ال10 MG الثانية ونكتبها في الملف الثاني .. وهكذا ..

لا أعلم .. لكن يحتاج المبرمج لاستخدام دالة مثل tellg ( كما فعل الاخ أمين ) , للاستعلام عن حجم الملف .. لذلك لابد من طريقة لاستيعاب حجم بمقدار 10 جيجا مثلاً .. هذا اذا كان هناك ملفات بهذا الحجم :) .

تم تعديل هذه المشاركة بواسطة الشمري في 3 أغسطس 2009 في 19:32

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#27

نعم الأحجام أكثر من 4 جيجا مدعومة في الأنظمة حاليا يالشمري وأظنها تحولت لتصبح 64bit بدلا من 32بت وهي الأربعة جيجا السابقة .

بالنسبة لما نحتاج :

1. الهاش قد يكون مهم لذلك يمكن جعله بأولوية أدنى في المشروع .

2. التشفير ياريت لو كان بسيط جدا , لأنه بشكل عام أغلب الملفات ستكون مضغوطة بعدها سنقسمها ببرنامجكم , ومع الهدر في كل جزء تصبح عملية الدمج صعبة جدا بدون معرفة طول الهدر وترتيب الملفات , بالتالي هي شبه كافية .

:)

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#28

قم بإستخدام النوع LONLONG و الذى يتيح لك التعامل مع الملفات الأكبر من 4 جيجا و اغلب دوال التعامل مع الملفات مثل ReadFileEx و WriteFileEx و SetPointerEx تعامل معها و بالتالى فالتعامل مع الملفات الأكبر من 4 جيجا متاح.

عموما قابلتنى هذه المشكله عندما كنت اعمل على البرنامج لذا فقد قمت بعمل class اسميتها File و التى سأقوم من خلالها بالتعامل مع الملف و هذا هو شكل الـ Header File الخاص بها.

النسخه التى اعمل عليها اصممها بشكل يتيح لها العمل من الـ command line او من GUI

 

[color= #007f00; font-style: italic;]/************************************************************************/

[color= #007f00; font-style: italic;]/* Class Name    : File                                                 */

[color= #007f00; font-style: italic;]/* Class Version : 2.0.2                                                */

[color= #007f00; font-style: italic;]/* Class Creator : Muhammad alaa                                        */

[color= #007f00; font-style: italic;]/* Creation Date : 03/08/2009 05:30 AM                                  */

[color= #007f00; font-style: italic;]/* Description   : this class wrapped windows API to connect to a file  */

[color= #007f00; font-style: italic;]/*                 and make manipulation on it                          */

[color= #007f00; font-style: italic;]/************************************************************************/

 

 

[color= #007f00;]#ifndef FILE_H

[color= #007f00;]#define FILE_H

 

 

[color= #007f00;]#include <Windows.h>

[color= #007f00;]#include <string>

[color= #007f00;]#include "enums.h"

[color= #007f00;]#include "ErrorCodes.h"

 

[color= #0000ff;]using std[color= #000000;]::[color= #808000;]string;

 

[color= #007f00;]// file class

[color= #0000ff;]class File

[color= #000000;]{

[color= #0000ff;]public[color= #000000;]:

 

    [color= #007f00;]////////////////////////

    [color= #007f00;]////  Constructors  ////

    [color= #007f00;]////////////////////////

 

    File[color= #000000;]([color= #000000;]); [color= #007f00;]// Default constructor

    File[color= #000000;](string sFileName[color= #000000;]); [color= #007f00;]// constructor with file name

    File[color= #000000;](ErrorHandler pErr[color= #000000;]); [color= #007f00;]// constructor with error handler

    File[color= #000000;](string sFileName, ErrorHandler pErr, OpenOptions eOpen[color= #000000;]); [color= #007f00;]// constructor with file name
 and error handler and open options

    File[color= #000000;](string sFileName, ErrorHandler pErr, OpenOptions eOpen, AccessOptions eAccess[color= #000000;]); [color= #007f00;]// con
structor with file name and error handler and open options and access options

    File[color= #000000;](string sFileName, ErrorHandler pErr, OpenOptions eOpen, AccessOptions eAccess, SharedO
ptions eShared[color= #000000;]); [color= #007f00;]// constructor with file name and error handler and open options and access op
tions and shared options

 

    [color= #007f00;]////////////////////

    [color= #007f00;]//// Destructor ////

    [color= #007f00;]////////////////////

 

    ~File[color= #000000;]([color= #000000;]); [color= #007f00;]// destructor

 

    [color= #007f00;]//////////////////////////////

    [color= #007f00;]//// Open & Close Methods ////

    [color= #007f00;]//////////////////////////////

 

    [color= #0000ff;]bool Open[color= #000000;]([color= #000000;]); [color= #007f00;]// open file

    [color= #007f00;]// flush only used when we write to a buffer and we not so it not make any sense

    [color= #007f00;]//bool Flush();  // flush data to file without closing

    [color= #0000ff;]bool Close[color= #000000;]([color= #000000;]); [color= #007f00;]// close opened file

 

    [color= #0000ff;]bool IsOpen[color= #000000;]([color= #000000;]);  [color= #007f00;]// is current file is opened

    [color= #0000ff;]bool IsClose[color= #000000;]([color= #000000;]); [color= #007f00;]// is current file is closed

 

    [color= #007f00;]//////////////////////////////

    [color= #007f00;]//// File Pointer Methods ////

    [color= #007f00;]//////////////////////////////

 

    [color= #0000ff;]void Seek[color= #000000;](LONGLONG iOffset[color= #000000;]); [color= #007f00;]// move file pointer to an offset

    [color= #0000ff;]void Seek[color= #000000;](LONGLONG iOffset, SeekOptions eSeek[color= #000000;]); [color= #007f00;]// move file pointer to an offset relative 
to an option

    LONGLONG getPosition[color= #000000;]([color= #000000;]); [color= #007f00;]// get current position

 

    [color= #0000ff;]bool IsBOF[color= #000000;]([color= #000000;]); [color= #007f00;]// is pointer in beginning of the file

    [color= #0000ff;]bool IsEOF[color= #000000;]([color= #000000;]); [color= #007f00;]// is pointer in end of the file

 

    LONGLONG getFileSize[color= #000000;]([color= #000000;]); [color= #007f00;]// get file size

 

    [color= #007f00;]/////////////////////////////

    [color= #007f00;]//// Reading and Writing ////

    [color= #007f00;]/////////////////////////////

 

    BYTE[color= #000000;]* ReadBytes[color= #000000;](LONGLONG iPosition,DWORD iCount[color= #000000;]); [color= #007f00;]// read number of bytes from specified po
sition

    [color= #0000ff;]bool  WriteBytes[color= #000000;](BYTE[color= #000000;]* pValue, UINT len, LONGLONG iPosition[color= #000000;]); [color= #007f00;]// write number of bytes star
ting from specified position

 

    [color= #0000ff;]inline BYTE[color= #000000;]* ReadBytes[color= #000000;](DWORD iCount[color= #000000;]) [color= #007f00;]// read number of bytes from current position

    [color= #000000;]{ [color= #0000ff;]return ReadBytes[color= #000000;](getPosition[color= #000000;]([color= #000000;]),iCount[color= #000000;]); [color= #000000;]}

    [color= #0000ff;]inline [color= #0000ff;]bool  WriteBytes[color= #000000;](BYTE[color= #000000;]* pValue, UINT len[color= #000000;]) [color= #007f00;]// write number of bytes starting from curr
ent position

    [color= #000000;]{ [color= #0000ff;]return WriteBytes[color= #000000;](pValue, len, getPosition[color= #000000;]([color= #000000;])[color= #000000;]); [color= #000000;]}

 

    [color= #0000ff;]template [color= #000000;]<[color= #0000ff;]class T[color= #000000;]>

    [color= #0000ff;]inline T[color= #000000;]*   Read[color= #000000;]([color= #000000;]) [color= #007f00;]// read an object from current position

    [color= #000000;]{ [color= #0000ff;]return [color= #000000;](T[color= #000000;]*[color= #000000;])ReadBytes[color= #000000;]([color= #0000ff;]sizeof T[color= #000000;]); [color= #000000;]}

 

    [color= #0000ff;]template [color= #000000;]<[color= #0000ff;]class T[color= #000000;]> 

    [color= #0000ff;]inline T[color= #000000;]*   Read[color= #000000;](LONGLONG iPosition[color= #000000;]) [color= #007f00;]// read an object starting from specified position

    [color= #000000;]{ [color= #0000ff;]return [color= #000000;](T[color= #000000;]*[color= #000000;])ReadBytes[color= #000000;](iPosition, [color= #0000ff;]sizeof T[color= #000000;]); [color= #000000;]}

 

    [color= #0000ff;]template [color= #000000;]<[color= #0000ff;]class T[color= #000000;]>

    [color= #0000ff;]inline [color= #0000ff;]bool Write[color= #000000;](T[color= #000000;]* pValue, UINT len[color= #000000;]) [color= #007f00;]// write an object to current position

    [color= #000000;]{ [color= #0000ff;]return WriteBytes[color= #000000;]([color= #000000;](BYTE[color= #000000;]*[color= #000000;])pValue, [color= #0000ff;]sizeof T [color= #000000;]* len[color= #000000;]); [color= #000000;]}

 

    [color= #0000ff;]template [color= #000000;]<[color= #0000ff;]class T[color= #000000;]>

    [color= #0000ff;]inline [color= #0000ff;]bool Write[color= #000000;](T[color= #000000;]* value, UINT len, LONGLONG iPosition[color= #000000;]) [color= #007f00;]// write an object to specified p
osition

    [color= #000000;]{ [color= #0000ff;]return WriteBytes[color= #000000;]([color= #000000;](BYTE[color= #000000;]*[color= #000000;])value, [color= #0000ff;]sizeof T [color= #000000;]* len, iPosition[color= #000000;]); [color= #000000;]}

 

    [color= #007f00;]/////////////////////////////

    [color= #007f00;]////      Accessors      ////

    [color= #007f00;]/////////////////////////////

 

    [color= #0000ff;]void   setFileName[color= #000000;](string sFileName[color= #000000;]); [color= #007f00;]// set file name

    string getFileName[color= #000000;]([color= #000000;]); [color= #007f00;]// get file name

 

    [color= #0000ff;]void   setErrorHandler[color= #000000;](ErrorHandler pErr[color= #000000;]); [color= #007f00;]// set error handler

    [color= #0000ff;]bool   IsErrorHandlerPresent[color= #000000;]([color= #000000;]); [color= #007f00;]// is error handler exist

 

    [color= #007f00;]/////////////////////////////

    [color= #007f00;]////   Static Function   ////

    [color= #007f00;]/////////////////////////////

 

    [color= #0000ff;]static [color= #0000ff;]bool FileExist[color= #000000;](string sFileName[color= #000000;]); [color= #007f00;]// is file exist

 

[color= #0000ff;]private[color= #000000;]:

    HANDLE       _hfile;     [color= #007f00;]// handle to an opened file

    string       _FileName;  [color= #007f00;]// file name

    ErrorHandler _err;       [color= #007f00;]// address of error function to be called

    LONGLONG     _SeekInternal_[color= #000000;](LONGLONG iLocation,SeekOptions eSeek[color= #000000;]); [color= #007f00;]// internal seek method

 

    OpenOptions   _eOpen;    [color= #007f00;]// open options

    AccessOptions _eAccess;  [color= #007f00;]// access options

    SharedOptions _eShared;  [color= #007f00;]// seek options

 

[color= #000000;]};

 

[color= #007f00;]#endif // FILE_H

و قد قمت بإرفاقها مع الملفات الأخرى التى تجعلها تساعدها على العمل.

من باب العلم فالـ header file المسمى ErrorCodes.h يحتوى على الداله FormatMessegeIntenal و التى مازالت فى قيد التطوير. [تم الإنتهاء منها]

FileClass.rar

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 3 أغسطس 2009 في 23:51

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

#29

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

قمت ببعض التطويرات لكى يتم الإختيار بين التقسيم بعدد الأجزاء و التقسيم بالحجم

وعند إدخال حجم الأجزاء بصوره خاطئه أكبر مثلا من حجم الملف الأساسى يقوم البرنامج بإنشاء نسخه من الملف الأصلى

وكذلك عند إدخال أحجام معينه يقوم البرنامج بإختيار حجم مناسب لكل جزء

وكتبت واجهه بدائيه للتسهيل من تجربة البرنامج

فى التقسيم

إدخال اسم الملف المراد تقسيمه مع الإمتداد طبعا

ثم إدخال حجم الجزء الواحد أو عدد الأجزاء حسب الإختار الذى بعده

ثم إدخال نوع التقسيم بالحجم s أو بالعدد n

ثم إدخال نوع الحجم byte او KB أو MB

فى الدمج فقط يتم إدخال اسم الملف الأصلى و اسم الملف الجديد بعد الدمج

الان اريد إدخال الهيدر فى الملفات

وكذلك ادخال امكانية التعامل مع سطر الأوامر

البرنامج فى المرفقات

سلام

files.rar

تم تعديل هذه المشاركة بواسطة amin_mu123 في 3 أغسطس 2009 في 23:38

اللهم صل على سيدنا محمد وعلى آله وصحبه وسلم

#30

جميل جدا يا شباب :)

كتبت نسخة بسيطة مثل وجدي "بدون header "، لكن بتاعتي تختلف منها بحيث لو مررت اسم اي جزء سيقوم ال Merger بالتعرف على البقية وضمهم .

ايضا البيانات مضغوطة داخل الملف يعني غير قابلة للقراءة :)

صورة لملف باك اب txt بعد تجزئته وفتح احد الاجزاء :

post-60254-1249345061_thumb.png

الله يخلي الدالة qCompress :P

# ./partfile -s db.sql 1000000
you are going to Split file:  "db.sql"
file size in Bytes:  5351229
"packet_db.sql_5351229_0"
"packet_db.sql_5351229_1000000"
"packet_db.sql_5351229_2000000"
"packet_db.sql_5351229_3000000"
"packet_db.sql_5351229_4000000"
"packet_db.sql_5351229_5000000"
Successful Split

مثلا نختار الجزء الخامس من الملف :

./partfile -m packet_db.sql_5351229_4000000
m_fileName:  "db.sql"
m_fileSize:  5351229
This in not part one , but we can deal with it ^_^
input:  "packet_db.sql_5351229_0"
input:  "packet_db.sql_5351229_1000000"
input:  "packet_db.sql_5351229_2000000"
input:  "packet_db.sql_5351229_3000000"
input:  "packet_db.sql_5351229_4000000"
input:  "packet_db.sql_5351229_5000000"
Successful Merge

تبقى ان احسب md5 sum لكل جزء ، ممكن استخدم crypto++ واخلص منها

المشكلة التي تواجهني الان وهي في حالة تم تغيير اسم ملف من الاجزاء ، كل الشغل حيكون راح !

السؤال هنا كيف امنع تغيير اسم الملف ؟ :wacko:

لقد جربت read-only ولكن ما نفعت ..

وبالنسبة لاخي الشمري ، اعتقد كل الحلول ستواجه مشكلة تغيير اسم احد الاجزاء . صحيح ؟

واعتقد الحل الامثل هنا هو انك تمسح الاجزاء وتعمل split من جديد :P

عندي اقتراح اخر ، لو كان الملف كبيرا ، لماذا لا نشغل اكثر من thread للتقسيم ..

اعتقد ستزيد السرعة والاداء ، والمشاكل ايضا :lol:

ساضع الكود بعد ان انتهي من حساب ال md5 sum وعمل واجهة بسيطة .

شكرا.

#31

اخي امين ال splitter لديك جميل ، لكن ال Merger لا يعمل الا بوجود الملف الاصلي ؟

هذا هكذا لديك ..

مثلا لو حذف الملف الاصلي وبقيت الاجزاء كيف سيتم ارجاعها في هذه الحالة ؟

هذه نقطة مهمة .

و بارك الله فيك ..

اضافة: الدالة itoa ليست قياسية ولا تعمل على ال Linux.

تم تعديل هذه المشاركة بواسطة SudaNix في 4 أغسطس 2009 في 05:07

#32

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

شكرا أخى sudanix على ملحوظاتك

ولكنى قمت بحذف الملف الأصلى بعد التقسيم وقمت بعمل الدمج فنجحت العمليه بلا مشاكل

وبالنسبه للدوال التى لم تعمل على ليونكس

فقمت بعمل داله خاصه تقوم بالعمل بدلا منها

وقمت بكتابة محاوله أخرى للبرنامج للتعامل معه من خلال سطر الأوامر

أتمنى أنك تراها وتبدى ملحوظاتك التى دائما تفيدنى

:D

تحياتى لك ولكل الأخوه فى المنتدى الرائع الذى تعلمت منه الكثير

فى أمان الله

الكود الجديد فى المرفقات

test.rar

تم تعديل هذه المشاركة بواسطة amin_mu123 في 4 أغسطس 2009 في 13:50

اللهم صل على سيدنا محمد وعلى آله وصحبه وسلم

#33

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

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

:lol:

المهم

جائتنى فكرة تشفير أو بمعنى أصح بعثرة للملفات المجزأه

على حسب كلمة سر أو رقم سرى معين

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

الآن لدينا أجزاء الملف غير معروف اين البدايه أو الوسط او النهايه اى مبعثره

وهذا طبعا بالنسبه لمن لا يعرف كلمة السر

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

فى الكود التالى

int main(int argc,char* argv[])
{
 Splitter s;
 s.Split("a.jpg",4,'n',"7645");
 Merger m1,m2,m3;
 m1.merge("a.jpg","new1.jpg","5476");
	m2.merge("a.jpg","new2.jpg","4567");
	m3.merge("a.jpg","new3.jpg","7645");
 return 0;
}

الداله split يمرر لها الملف المراد تقسيمه ثم عدد الأجزاء ثم حرف n لأننا سنقسم حسب عدد الأجزاء

ثم رقم سرى ويمكن استخدام حروف ولاحظ أن عدد الأرقام مثلث عدد الملفات المنتجه

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

وبعد ذلك أنشئنا ثلاث كائنات دمج ومررنا لها اسم الملف الأصلى واسم الملف الجديد ثم الرقم السرى

كلا منهم سيدمج ولكن ايهم سينجح فى ايجاد الملف الحقيقى طبعا m3 لأننا مررنا له الترتيب الحقيقى

التطبيق بأكمله فى المرفقات

سؤال :

اريد عمل تطبيق بإستخدام c++ builder فهل برامجه تعمل على الينكس

بصراحه لم اجربه من قبل

الآن ان شاء الله سأقوم بإضافة هيدر بسيط للملفات حتى يتم التحقق من صحتها أثناء التجميع

سلام

spme.rar

اللهم صل على سيدنا محمد وعلى آله وصحبه وسلم

#34

انتهيت تقريبا من عمل الـ Splitter و كانت احد المشاكل التى واجهتنى هى فى حال اردت عمل تقسيم لملف 8 جيجا بمساحة 500 ميجا للملف الواحد تصبح العمليه بطيئه حيث انى اقوم بإنشاء الملف و بعدها اخذ 30 ميجا داخل الـ buffer ثم اكتبها داخل الملف و حيث ان الملف مساحته صفر فيقوم بعمل extend لمساحة الملف مما قد يجعل نظام التشغيل يقوم بعملية defrage للملف اثناء كتابته. فبحثت عن حل لهذه المشكله ووجدت اننى من الممكن ان اجعل نظام التشغيل بأن يقوم بحجز مساحة الملف بشكل كامل و بعد ذلك عندما اقوم بالكتابه فكل ما افعله حينها هو overwrite للبيانات الموجوده (حيث ان نظام التشغيل لا يقوم بعمل zeroing للملف).

هذه الخطوات تتم كالتالى

1 - قم بإنشاء ملف جديد بإستخدام CreateFile.

2 - قم بوضع مؤشر الكتابه SetFilePointerEx للمساحة التى تريد جعلها للملف.

3 - قم بإستخدام الداله SetEndOfFile لوضع مؤشر الكتابه فعليلا فى هذا المكان.

4 - استخدم الداله SetFileValidData و مرر لها نفس الرقم التى مررته فى رقم 2 لجعل نظام التشغيل يقوم بحجز المساحه فعليا للملف.

قمت بتطوير الكلاس File و قمت بإضافة الداله setFileSize و التى تقوم بالسابق.

لاحظ ان يمكن للخطوات السابقه ان تزيد او تنقص من حجم الملف هذا يعتمد على المساحه التى تمررها.

الكود فى المرفقات

FileClass.rar

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 5 أغسطس 2009 في 05:38

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

#35

اكتشفت خطأ فى File Class داخل الدالتين ReadBytes و WriteBytes

داخل الدالتين يوجد هذا السطر

 

	OVERLAPPED o;

	o.[color= #808000;]Offset [color= #000000;]= [color= #000000;](DWORD[color= #000000;])[color= #000000;](iPosition [color= #000000;]& 0x00000000FFFFFFFF[color= #000000;]);

	o.[color= #808000;]OffsetHigh [color= #000000;]= [color= #000000;](DWORD[color= #000000;])[color= #000000;](iPosition [color= #000000;]>> [color= #ff0000;]4[color= #000000;]);

قم بتغيير الرقم 4 ليصبح 32.

نسيت انه بيتم التعامل على مستوى البت مش البايت

فى حال تجربة الدالتين على وضعهم القديم قد تسبب مشكله كبيره بيتم حجز مساحات بشكل عشوائى (تعدت معى 12 جيجا فى ملف واحد).

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

#36

انتهيت بنسبه كبيره من Splitter Class و كل ما يتبقى فيها هو تشفير محتوايات الملف فى حالة وجود باسورد و كذلك حساب الهاش للملف و للـ header (بالنسبه للـ header حتى اتأكد من انه سليم).

بعد ان انتهيت من الـ Splitter قمت بعمل بعض التحسينات عليه هو و File Class و قمت بعمل بعض التجارب و هذه النتيجه النهائيه :

ملحوظه تم استخدام Buffer بمساحة 30 ميجا

1 - التجربه على هارد SATA (الملف يقوم بزيادة حجمه فى كل مره يكتب فيها بداخله)

A - تقسيم ملف مساحته 700 ميجا إلى 100 ميجا للملف الواحد (يعنى 7 ملفات) تأخذ 12 ثانيه و 7 اجزاء من الثانيه.

B - تقسيم ملف مساحته 5.52 جيجا إلى 750 ميجا للملف الواحد (يعنى 8 ملفات) تأخذ 3 دقائق و 10 ثوانى و 18 جزء من الثانيه.

2 - التجربه على هارد SATA (يتم حجزء مساحه كامله للملف و يتم عمل overwrite للبيانات الموجوده داخله)

A - تقسيم ملف مساحته 700 ميجا إلى 100 ميجا للملف الواحد (يعنى 7 ملفات) تأخذ 1 دقيقه و 2 ثانيه و 1 جزء من الثانيه.

B - تقسيم ملف مساحته 5.52 جيجا إلى 750 ميجا للملف الواحد (يعنى 8 ملفات) تأخذ 8 دقائق و 19 ثانيه و 91 جزء من الثانيه.

3 - التجربه على هارد IDE - PATA (الملف يقوم بزيادة حجمه فى كل مره يكتب فيها بداخله)

A - تقسيم ملف مساحته 700 ميجا إلى 100 ميجا للملف الواحد (يعنى 7 ملفات) تأخذ 26 ثانيه و 50 اجزاء من الثانيه.

B - تقسيم ملف مساحته 5.52 جيجا إلى 750 ميجا للملف الواحد (يعنى 8 ملفات) تأخذ 3 دقائق و 42 ثوانى و 5 جزء من الثانيه.

4 - التجربه على هارد IDE - PATA (يتم حجزء مساحه كامله للملف و يتم عمل overwrite للبيانات الموجوده داخله)

A - تقسيم ملف مساحته 700 ميجا إلى 100 ميجا للملف الواحد (يعنى 7 ملفات) تأخذ 49 ثانيه و 79 جزء من الثانيه.

B - تقسيم ملف مساحته 5.52 جيجا إلى 750 ميجا للملف الواحد (يعنى 8 ملفات) تأخذ 8 دقائق و 32 ثانيه و 42 جزء من الثانيه.

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

سأقوم برفعها لكم قريبا و لكن بعد التأكد بشكل تام من صحتها

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

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 6 أغسطس 2009 في 03:35

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

#37
اقتباس
هذا الموضوع جذبنى كتير صراحه

:D .

بالنسبة للتشفير , أو بعثرة الملفات .. أظن المطلوب هو أن نمنع أي مستخدم من أن يعرف محتويات الملفات المجزئة .. افرض أنك جزأت ملف نصي .. الى 10 أجزاء .. هل يمكنك في هذه الحالة مشاهدة محتويات أحد الاجزاء عن طريق المفكرة ؟

لا أعرف اذا كان الفهم صحيحا .

الاخ محمد علاء :

المرفق معطوب .. تظهر فقط بعض الملفات .. ياليت ترفعها مرة ثانية ..

بالمناسبة .. الأخ محمد علاء قام بتطوير Class باستخدام Win32 API ويدعم 64 بت ... للقراءة من والى الملفات .

قمت بكتابة Class مشابه ( بمميزات أقل ) .. باستخدام c++ std::fstream .. وعملت Splitter حسب الحجم .. ولم تظهر مشاكل حتى الان باستثناء مشكلة الملفات الضخمة .

لذلك يمكننا عمل واجهة interface , ونعمل implementation لها حسب نظام التشغيل :

( قصاصة توضيحية فقط ) :

post-42837-1249470764_thumb.png

من الجميل أن نصل في النهاية لكود يجمع نقاط القوّة من كل برنامج طرحه الاعضاء .

بالرغم من أني أفضل أن لا نستعجل بطرح البرامج قبل تحليل البرنامج ومعالجة المشاكل بشكل كامل .. ( نظريا ) .

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

أعتقد أن حل مشكلة البطء بشكل كامل .. يعتمد على مفهوم File Mapping , كما ذكر الاخ وجدي ... لا أعرف هل تستخدمها أم لا .. بانتظار رؤية الكود .

تم تعديل هذه المشاركة بواسطة الشمري في 5 أغسطس 2009 في 14:19

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#38

كما لاحظت اخى المشرى فالبطء موجود فقط فى حالة ان الملف قد تم حجز مساحته من قبل و يتم التعديل فيه لذا فقد تجنبتها و حقيقى اصبح الـ Splitter افضل كثيرا.

بالنسبه للكود فأنا اقوم بوضع ملاحظات عليه حتى يفهم من يقرءه السبب فى وجوده و عندما اقوم بالإنتهاء منه سأرفعه لكم (فى خلال ساعه ان شاء الله).

بالنسبه للتشفير : لا اعرف منتظرين رأى باقى الأخوه و حالما نستقر على شئ سأقوم بتطبيقه و لكن المتفق عليه حتى الأن هو الهاش الخاص بالملف و انا اقوم بعمل الكلاس الخاصه به فى الوقت الحالى.

بالنسبه لموضوع الـ interface فهو موضوع جميل سيجعل الكود portable.

ملاحظه : انا لا استخدم الـ File Mapping داخل الـ File Class و لكن نظام عملها شبيه به قليلا.

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

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

#39

أخى الشمرى :rolleyes:

فكرتى فاشله طبعا مع ملفات التكست

وكذلك لها عيوب فى إختيار كلمة السر لأنه لو كان هناك رقمان او حرفان متشابهان ستنهار عمليه التقسيم بأكملها

:)

بس هى أفكار وبنجرب معها

تحياتى

اللهم صل على سيدنا محمد وعلى آله وصحبه وسلم

#40

هذه هى النسخه التى اعمل عليها قمت بترتيب الكود و مراجعته و كتابة ملاحظات عليه حتى يتسنى لكم التعامل معه او التعديل عليه اذا رغبتم بذلك، الكود فى المرفقات و التالى هو شرح سريع لما يحتويه الملف.

يحتوى الملف على اربع فولدرات و هم File و Header و Manager و Other

File : يحتوى على الـ Class التى يقوم عليها البرنامج (بإعتبار ما سيكون ان شاء الله) و هى File و معها الملف enums و الذى يحتوى على enums تحتاجها الـ Class.

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

Manager : يحتوى (حتى الأن) على Class واحده فقط و هى Splitter و التى تقوم بتجزئة اى ملف و تقوم بإضافة MainHeader لكل الملفات المجزئه.

Other : يحتوى على بعض الـ Classes و الدوال المساعده منها Path class و التى تقوم بعمل عمليات على مسارات و اسماء الملفات و ErrorCodes و التى تمثل نظام تتبع الأخطاء داخل جميع الفئات بالبرنامج.

FileManager.rar

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

#41

السلام عليكم

دلوقتى انا عملت كلاس سمتها CRC32 و ده شكلها

 

[color= #007f00;]#ifndef CRC32_H

[color= #007f00;]#define CRC32_H

 

[color= #007f00;]#include "../File/File.h"

[color= #007f00;]#include <Windows.h>

 

[color= #0000ff;]class CRC32

[color= #000000;]{

[color= #0000ff;]public[color= #000000;]:

	CRC32[color= #000000;]([color= #000000;]);

	~CRC32[color= #000000;]([color= #000000;]);

 

	DWORD CalcCRC32[color= #000000;](File[color= #000000;]* fFile,LONGLONG lFrom, LONGLONG lTo[color= #000000;]);

 

	[color= #0000ff;]inline DWORD CalcCRC32[color= #000000;](File[color= #000000;]* fFile[color= #000000;])

	[color= #000000;]{

		[color= #0000ff;]if [color= #000000;](fFile[color= #000000;]-[color= #000000;]>IsClose[color= #000000;]([color= #000000;])[color= #000000;]) fFile[color= #000000;]-[color= #000000;]>Open[color= #000000;]([color= #000000;]);

		[color= #0000ff;]if [color= #000000;](fFile[color= #000000;]-[color= #000000;]>IsClose[color= #000000;]([color= #000000;])[color= #000000;]) [color= #0000ff;]return [color= #ff0000;]0;

		[color= #0000ff;]return CalcCRC32[color= #000000;](fFile, [color= #ff0000;]0, fFile[color= #000000;]-[color= #000000;]>getFileSize[color= #000000;]([color= #000000;])[color= #000000;]);

	[color= #000000;]}

 

	[color= #0000ff;]inline DWORD CalcCRC32[color= #000000;](File[color= #000000;]* fFile,LONGLONG lFrom[color= #000000;])

	[color= #000000;]{

		[color= #0000ff;]if [color= #000000;](fFile[color= #000000;]-[color= #000000;]>IsClose[color= #000000;]([color= #000000;])[color= #000000;]) fFile[color= #000000;]-[color= #000000;]>Open[color= #000000;]([color= #000000;]);

		[color= #0000ff;]if [color= #000000;](fFile[color= #000000;]-[color= #000000;]>IsClose[color= #000000;]([color= #000000;])[color= #000000;]) [color= #0000ff;]return [color= #ff0000;]0;

		[color= #0000ff;]return CalcCRC32[color= #000000;](fFile, lFrom, fFile[color= #000000;]-[color= #000000;]>getFileSize[color= #000000;]([color= #000000;])[color= #000000;]);

	[color= #000000;]}

 

	DWORD CalcCRC32[color= #000000;](BYTE[color= #000000;]* pArray, UINT iCount, UINT iFrom, UINT iTo[color= #000000;]);

 

	[color= #0000ff;]inline DWORD CalcCRC32[color= #000000;](BYTE[color= #000000;]* pArray, UINT iCount[color= #000000;])

	[color= #000000;]{ [color= #0000ff;]return CalcCRC32[color= #000000;](pArray, iCount, [color= #ff0000;]0, iCount[color= #000000;]); [color= #000000;]}

 

	[color= #0000ff;]inline DWORD CalcCRC32[color= #000000;](BYTE[color= #000000;]* pArray, UINT iCount, UINT iFrom[color= #000000;])

	[color= #000000;]{ [color= #0000ff;]return CalcCRC32[color= #000000;](pArray, iCount, iFrom, iCount[color= #000000;]); [color= #000000;]}

 

	[color= #0000ff;]inline DWORD CalcCRC32[color= #000000;]([color= #0000ff;]const [color= #0000ff;]char[color= #000000;]* szValue,UINT iCount[color= #000000;])

	[color= #000000;]{ [color= #0000ff;]return CalcCRC32[color= #000000;]([color= #000000;](BYTE[color= #000000;]*[color= #000000;])[color= #0000ff;]const_cast[color= #000000;]<[color= #0000ff;]char[color= #000000;]*[color= #000000;]>[color= #000000;](szValue[color= #000000;]),iCount, [color= #ff0000;]0, iCount[color= #000000;]); [color= #000000;]}

 

	[color= #0000ff;]template[color= #000000;]<[color= #0000ff;]typename T[color= #000000;]>

	[color= #0000ff;]inline DWORD CalcCRC32[color= #000000;](T[color= #000000;]* pObject[color= #000000;])

	[color= #000000;]{ [color= #0000ff;]return CalcCRC32[color= #000000;]( [color= #000000;](BYTE[color= #000000;]*[color= #000000;])pObject, [color= #0000ff;]sizeof T, [color= #ff0000;]0, [color= #0000ff;]sizeof[color= #000000;](T[color= #000000;])[color= #000000;]); [color= #000000;]}

 

[color= #0000ff;]private[color= #000000;]:

	UINT[color= #000000;]*  _crcTable;

[color= #000000;]};

[color= #007f00;]#endif

دلوقتى فى حالة عمل split لملف فانا بحسب الـ checksum للـ buffer مع كل لفه داخل اللوب و بالتالى المستخدم مبيحسش بيها.

لكن فى حالة الملفات الكبيره و القصود فى حالة الـ merge دلوقتى المفترض انى اعمل check على محتويات الملف و بإفتراض ان حجم الملف الواحد 750 (زى المثال اللى انا كاتبه فى المشاركه رقم 36) فبالتالى انا المفترض هعمل check sum على 750 ميجا (مساحة الملف الواحد) * عدد الملفات اللى هيتم دمجها.

سؤالى هو هل فى طريقه اقدر اعمل checksum على المف بدون عمل mapping له فى الـ memory ؟؟

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

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 6 أغسطس 2009 في 18:20

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

#42

نقطه اخرى لم يقم الأخوه الأعضاء بالإتفاق على موضوع التشفير حتى الأن بمعنى اوضح هل سيتم عمل تشفير بإستخدام باسورد ام لا

فانا على وشك الإنتهاء من الكود و بعدها سأبدء بتصميم UI

ملحوظه : قمت بعمل تعديل على Splitter Class ليكون الـ Buffer المستخدم وقت تقسيم الملف يساوى 12% من المساحة الفارغه من النظام فى الوقت الحالى و ذلك حتى تكون ديناميكيه اكثر فى التعامل.

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 6 أغسطس 2009 في 15:47

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

#43

قمت بعمل اضافات و تعديلات و تحسينات على المشروع ، النسخه الجديده فى المرفقات

ستجد فى المشروع الجديد الفولدرات التاليه :

File: و يحتوى على الكلاس File والملف enums.

Hash: و يحتوى على الكلاس CRC32 و التى تتيح لك عمل checksum.

Header: و يحتوى على Mainheader struct و الذى تم الإنتهاء منه بكتابة الأكواد للدوال التى لم يكن تم تضمنيها مثل IsHeaderOK و CheckPassword.

Manager: و يحتوى على النسخه المبدئيه من الكلاس (لا يوجد بها دوال حتى الأن) و يحتوى على النسخه المطوره من الكلاس Splitter و لاتى الأن تدعم CRC32 على بيانات الملف المقسم و كذلك الـ header و كلمة المرور.

Memory: هى دوال خاصه بالتعامل مع الذاكره و تحتوى على الداله+uffershBufferSizes و التى تقوم بعمل Refresh للمساحة التى سيتم استخدامها كـ buffer.

Other: و يحتوى على الكلاس Path و ملف الـ ErrorCodes

Time: و يحتوى على الكلاس HRTimer و التى استخدمها فى قياس سرعة تنفيذ الكود و ايضا تحتوى على TimeSpan struct و الذى يتيح معرفة الأيام و الساعات و الدقائق و الثوانى و millisecond و nanosecond و ايضا الـ ticks. توجد داله داخل الكلاس HRTimer اسمها getTimeSpan تعود لك بنسخه فعاله من الوقت المنقضى داخل الـ Timer.

ايضا يوجد فولدرين فارغين و هم CommandLine و Console و الذين سيحتووا فيما بعد على كلاس لتحليل محتويات الـ CommandLine و كذلك الكلاس Console و التى تتيح لك استخدام الـ Console من داخل برنامج GUI او جعلها هى النسخه الفعاله من البرنامج.

FileManager.rar

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 7 أغسطس 2009 في 08:06

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

#44

ما شاء الله تبارك الله

جزاك الله خيرا

بجد شغل إحترافى ,, وفقك الله دنيا وأخرى

اللهم صل على سيدنا محمد وعلى آله وصحبه وسلم

#45

فى الوقت الحالى اعمل على Merger Class و لكن تواجهنى مشكلة عدم معرفة المستخدم بمقدار البيانات التى تم نسخها إلى الملف النهائى و بالتالى فقمت بالرجوع للـ File Class حتى اقوم بعمل تعديل فيها يتيح معرفة ذلك (كنت قد حاولت من قبل و عندما باءت معى بالفشل اكثر من مره تركتها إلى أجل مسمى)، سأشرح الفكره بالتفصيل عسى ان يستطيع احد معرفة كيفية حلها.

المعامل الأخير للدالتين ReadFileEx و WriteFileEx عباره عن مؤشر لداله يتم تنفيذها من قبل نظام التشغيل اثناء الكتابه او القراءه، هذه الداله تأخذ الشكل التالى:

 

[color= #0000ff;]VOID CALLBACK FileIOCompletionRoutine[color= #000000;](DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVE
RLAPPED lpOverlapped [color= #000000;]);

فى البدايه لن استطيع وضع هذه الداله كـ member function داخل الـ class لأن المترجم يقوم بإضافة معامل جديد قبل اى معامل من معاملات و هو this و بالتالى سيقوم بتعديل المعاملات الخاصه بالداله FileIOCompletionRoutine و بهذا لن استطيع تمريرها لدوال الكتابه و القراءه و بالتالى قمت بجعلها static حتى لا يقوم المترجم بتعديل بصمة الداله و لكن ظهرت مشكله جديده و هى انه لن استطيع التعامل مع المتغيرات الموجوده بالـ Class كذلك الكود المكتوب داخل هذه الداله سيكون مشترك بين جميع نسخ الـ File class الموجوده و الحل هنا يكمن فى المعامل قبل الأخير الذى يتم تمريره لدوال القراءه و الكتابه و هو OVERLAPPED حيث يحتوى على متغير اسمه hEvent هذا المتغير فى حالة دوال القراءه و الكتابه لا يقوم نظام التشغيل بالتعامل معه و بالتالى يمكننى استخدامه لذا فقمت بتمرير this له.

 

[color= #0000ff;]class File

[color= #000000;]{

   ..

   ..

	[color= #808000;]BYTE* ReadBytes[color= #000000;](LONGLONG, DWORD[color= #000000;]);

	[color= #0000ff;]bool  WriteBytes[color= #000000;](BYTE[color= #000000;]*, UINT, LONGLONG[color= #000000;]);

   ..

   ..

[color= #0000ff;]private[color= #000000;]:

   	[color= #0000ff;]static [color= #0000ff;]void [color= #0000ff;]_stdcall ReadFileIOCompletionRoutine[color= #000000;](DWORD, DWORD, LPOVERLAPPED[color= #000000;]);

	[color= #0000ff;]static [color= #0000ff;]void [color= #0000ff;]_stdcall WriteFileIOCompletionRoutine[color= #000000;](DWORD, DWORD, LPOVERLAPPED[color= #000000;]);

[color= #000000;]};

 

BYTE[color= #000000;]* File[color= #000000;]::[color= #808000;]ReadBytes[color= #000000;](LONGLONG iPosition,DWORD iCount[color= #000000;])

[color= #000000;]{

        ...

        ...

        ...

        ...

 

	[color= #808000;]LPVOID value [color= #000000;]= [color= #0000ff;]new BYTE[color= #000000;][iCount[color= #000000;]];

 

	OVERLAPPED o;

	ZeroMemory[color= #000000;]([color= #000000;]&o, [color= #0000ff;]sizeof[color= #000000;](OVERLAPPED[color= #000000;]) [color= #000000;]);

 

	o.[color= #808000;]Offset [color= #000000;]= [color= #000000;](DWORD[color= #000000;])[color= #000000;](iPosition [color= #000000;]& 0x00000000FFFFFFFF[color= #000000;]);

	o.[color= #808000;]OffsetHigh [color= #000000;]= [color= #000000;](DWORD[color= #000000;])[color= #000000;](iPosition [color= #000000;]>> [color= #ff0000;]32[color= #000000;]);

	o.[color= #808000;]hEvent [color= #000000;]= this; [color= #007f00;]// store address of this instance in hEvent

 

	[color= #0000ff;]if [color= #000000;](ReadFileEx[color= #000000;](_hfile,value,iCount,[color= #000000;]&o,File[color= #000000;]::[color= #808000;]ReadFileIOCompletionRoutine[color= #000000;]) [color= #000000;]== [color= #ff0000;]0[color= #000000;])

	[color= #000000;]{

		RAISE_EEROR[color= #000000;](_err, GetLastError[color= #000000;]([color= #000000;])[color= #000000;]);

		[color= #0000ff;]return [color= #ff0000;]0;

	[color= #000000;]}

 

	[color= #0000ff;]return [color= #000000;](BYTE[color= #000000;]*[color= #000000;])value;

[color= #000000;]}

 

[color= #0000ff;]bool File[color= #000000;]::[color= #808000;]WriteBytes[color= #000000;](BYTE [color= #000000;]*pValue, UINT iCount, LONGLONG iPosition[color= #000000;])

[color= #000000;]{

        ...

        ...

        ...

        ...

 

	[color= #808000;]OVERLAPPED o;

	ZeroMemory[color= #000000;]([color= #000000;]&o, [color= #0000ff;]sizeof[color= #000000;](OVERLAPPED[color= #000000;]) [color= #000000;]);

 

	o.[color= #808000;]Offset [color= #000000;]= [color= #000000;](DWORD[color= #000000;])[color= #000000;](iPosition [color= #000000;]& 0x00000000FFFFFFFF[color= #000000;]);

	o.[color= #808000;]OffsetHigh [color= #000000;]= [color= #000000;](DWORD[color= #000000;])[color= #000000;](iPosition [color= #000000;]>> [color= #ff0000;]32[color= #000000;]);

	o.[color= #808000;]hEvent [color= #000000;]= this; [color= #007f00;]// store address of this instance in hEvent

 

	[color= #0000ff;]if [color= #000000;](WriteFileEx[color= #000000;](_hfile,pValue,iCount,[color= #000000;]&o,File[color= #000000;]::[color= #808000;]WriteFileIOCompletionRoutine[color= #000000;]) [color= #000000;]== [color= #ff0000;]0[color= #000000;])

	[color= #000000;]{

		RAISE_EEROR[color= #000000;](_err, GetLastError[color= #000000;]([color= #000000;])[color= #000000;]);

		[color= #0000ff;]return false;

	[color= #000000;]}

 

	[color= #0000ff;]return true;

[color= #000000;]}

 

[color= #0000ff;]void [color= #0000ff;]_stdcall File[color= #000000;]::[color= #808000;]ReadFileIOCompletionRoutine[color= #000000;](DWORD ErrorCode, DWORD BytesTransfered, LPOVERL
APPED lpOverlapped[color= #000000;])

[color= #000000;]{

        ...

        ...

[color= #000000;]}

 

[color= #0000ff;]void [color= #0000ff;]_stdcall File[color= #000000;]::[color= #808000;]WriteFileIOCompletionRoutine[color= #000000;](DWORD ErrorCode, DWORD BytesTransfered, LPOVER
LAPPED lpOverlapped[color= #000000;])

[color= #000000;]{

        ...

        ...

[color= #000000;]}

المشكله هنا انه لا يتم استدعاء WriteFileIOCompletionRoutine او ReadFileIOCompletionRoutine و عندما راجعت شرح الدالتين مره اخرى و جدت انه عند فتح الملف بإستخدام CreateFile لابد من جعل احد خصائص الملف FILE_FLAG_OVERLAPPED و لكن حتى مع تمريره لم يتم استدعاء الدالتين بالإضافه انه تطلب منى محاولة حل مشكلة التزامن فى القراءه و الكتابه من و الى الملفات حتى تتم المعمليه بشكل سليم.

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

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

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 8 أغسطس 2009 في 14:32

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

#46

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

آخر التعديلات على برنامجى البدائى

:lol:

Merger & Splitter = MeSp

mesp.rar

اللهم صل على سيدنا محمد وعلى آله وصحبه وسلم

#47

هل من مساعده :cry:

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

#48

الحمد لله انتهيت من عمل الـ Merger و بالتالى تكون الـ Classes جاهزه للعمل

و بالتالى ينقص النسخه 3 فئات فقط و هم

1 - Manager : و التى تقوم بالبحث عن الملفات التى سيتم دمجها فى ملف واحد ثم تمريرها للكلاس Merger، ايضا تقوم بالتحقق من ان كل الملفات المدخله يندرجوا تحت GUID واحد و التحقق من الـ CRC الخاص بهم.

2 - Console : و التى تتيح التعامل مع البرنامج داخل الـ Console كبديل لـ GUI الرئيسيه.

3 - CommandLine : و هو Parser للـ command line.

اما بالنسبه للنسخه الحاليه فقمت بعمل بعض التعديلات على بعض الفئات الموجوده.

FileManager.rar

و هذا مثال لاستخدام الـ Splitter

ملاحظات على المثال : لا تقم بإدخال بيانات خاطئه لإنى لم اقم بكتابة اى كود لتتبع مدخلات المستخدم و بالتالى فإن تمت ادخال اى بيانات خاطئه ممكن ان تسبب فى انهيار البرنامج. السبب فى عدم كتابة كود تتبع الأخطاء هو لجعل المثال صغير.

 
#include "Other/ErrorCodes.h"
#include "File/File.h"
#include "Manager/Splitter.h"

#include <iomanip>
#include <Windows.h>
#include <iostream>
using namespace std;

string current_file_name;
void SplitHandler (string FileName, UINT PartNumber, LONGLONG PartSize, LONGLONG BytesTransfered);

void main()
{
	string file_to_split;
	cout << "Enter path and name of file to split.  ex: C:TestFolderTest.rar\n";
	getline(cin, file_to_split);

	string path_to_split;
	cout << "\nEnter path to split file in. ex: C:TestFolder\n";
	getline(cin, path_to_split);

	string name_to_split;
	cout << "\nEnter name of the output file. ex: Test.rar\n";
	getline(cin, name_to_split);

	LONGLONG size_to_split;
	cout << "\nEnter Size to split in Bytes\n";
	cin >> size_to_split;

	if (size_to_split < 65)
	{
		cout << "split size can not less than 65 bytes\n";
		system("pause");
		return;
	}

	File f(file_to_split,NULL,OpenOptions::Open,AccessOptions::Read,SharedOptions::Exclusive);
	f.Open();

	if (f.IsClose())
	{
		cout << "failed to open input file "" << file_to_split << "\"\n";
		system("pause");
		return;
	}

	cout << "\n\nStart Splitting\n\n";

	Splitter s(&f,size_to_split);
	s.setSplitCallback(SplitHandler);

	s.setSplitPath(path_to_split);
	s.setSplitFileName(name_to_split);
	s.setSplitSize(size_to_split);

	s.Split();
	f.Close();

	cout << "\n\nDone..\n" << endl;
	system("pause");
}

void SplitHandler (string FileName, UINT PartNumber, LONGLONG PartSize, LONGLONG BytesTransfered)
{
	if (current_file_name.size() == 0) current_file_name = FileName;

	float percent = (float)BytesTransfered * 100 / PartSize;

	if (current_file_name == FileName)
		cout << '\r';
	else
	{
		cout << '\n';
		current_file_name.clear();
	}

	cout << setprecision(3);
	cout << FileName << " " << setw(3) << percent << "% completed";
}

و هذا مثال على استخدام الـ Merger : نفس الملاحظه للـ Splliter تنطبق هنا

 
#include "Other/ErrorCodes.h"
#include "File/File.h"
#include "Manager/Merger.h"

#include <iomanip>
#include <Windows.h>
#include <iostream>
using namespace std;

string current_file_name;
string dest_file;
void MergeHandler (string SourceFileName, LONGLONG DestinationFileSize,
				   LONGLONG CurrentFileSize, LONGLONG CurrentBytesTransfered,
				   LONGLONG OverallBytesTransfered);

void main()
{
	cout << "Enter destination file path and name. ex: c:test.rar\n";
	getline(cin,dest_file);

	string files_path;
	cout << "\nEnter path which files to merge exists.\n";
	getline(cin,files_path);

	if (files_path.c_str()[files_path.size()-1] != '') files_path += "";

	UINT iCount;
	string dummy;
	cout << "nEnter number of files to mergen";
	getline(cin,dummy);
	iCount = atoi(dummy.c_str());

	string* arrFiles = new string[iCount];
	cout << "\nAdd Files to merge them: "only file names don't include path" ex. File.ext \n";

	for(UINT i = 0; i<iCount; i++)
	{
		cout << setfill('0') << setw(2) << i+1 << ": ";
		getline(cin,arrFiles);
		arrFiles = files_path + arrFiles;
	}

	cout << "\n\nMerging..\n\n";

	Merger m(arrFiles,iCount,dest_file);
	m.setMergeCallback(MergeHandler);

	m.Merge();

	cout << "\n\nDone...\n";

	system("pause");
}

void MergeHandler (string SourceFileName, LONGLONG DestinationFileSize, LONGLONG CurrentFileSize,
				   LONGLONG CurrentBytesTransfered, LONGLONG OverallBytesTransfered)
{
	string source_file = SourceFileName.substr(SourceFileName.find_last_of('\\')+1);
	string destin_file = dest_file.substr(dest_file.find_last_of('\\')+1);

	if (current_file_name.size() == 0) current_file_name = SourceFileName;

	int percent = OverallBytesTransfered * 100 / DestinationFileSize;

	if (current_file_name == SourceFileName)
		cout << '\r';
	else
	{
		cout << '\n';
		current_file_name.clear();
	}

	cout << "Merge File "" << source_file
		 << "" into File "" << dest_file
		 << "" : " << setfill('0') << setw(2)
		 << percent << "% completed";
}

ملاحظه اخيره: عملية التقسيم و التجميع سرعتها على حسب ما يوجد لديك من ذاكره حيث يستغل البرنامج 12% من الذاكره المتاحه للتقسيم او التجميع.

قد تلاحظ ان النسبة المئويه للتقسيم التى ستظهر داخل المثال السابق غالبا ما تكون 100% للملف الواحد و ذلك لإن البرنامج يعتمد على طريقه ديناميكيه للتقسيم و هى بإختصار اذا كانت مساحة الـ 12% من الذاكره هى 150 ميجا و كانت المساحة التى تريدها للتقسيم تساوى 70 ميجا فسيتم استخدام الـ 70 ميجا بدلا من 150 ميجا للحفاظ على الذاكرهز نفس الطريقه توجد بالتجميع و ايضا حساب الـ CRC32 للملفات.

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

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 12 أغسطس 2009 في 15:27

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

#49

يبدو انه هناك سوء تفاهم بين الـ Escape Sequence و التاج GCODE و CODE

لذا فقد صححت المثاليين و وضعتهم فى المرفقات.

Examples.rar

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 12 أغسطس 2009 في 17:52

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

#50

السلام عليكم ...

ما شاء الله الأخ محمد صاحب همة عالية جداً, أتمنى لك التوفيق في إكمال البرنامج أخي محمد :)

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

لا يزال المشروع في بالي, و إن شاء الله سأضع محاولة متواضعة عندما أجد الوقت الكافي,

تحياتي ..

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