گفتگو هایی در باب سی شارپ

the_king

مدیرکل انجمن
خیلی ممنونم استاد علی
الان من یه بکاپ دارم از درایو f ام و حجمش 25 مگابایت بود. فایلی که 800 مگابایت بود را از توی درایو حذف کردم (این بکاپ شامل این فایل هم میشه) . بعد از حذف ، حجم بکاپ 31 مگابایت شد . یعنی 6 مگابایت فقط افزایش پیدا کرد . بعد هم فایل حذف شده را ریکاوری کردم .
روندش چجوری هه؟!
اگه این روند میبود ، باید 800 مگ به حجم بکاپ اضافه میشد ولی این 6 مگ فقط اضافه شد.
داده های فایل روی هارد دیسک هست، داده ها پاک نشده، فقط اسمش از لیست حذف شده، هر زمانی که داده های اون فایل برای استفاده فایل دیگری بازنویسی بشه نیاز به ثبت اش در backup پیش میاد. همانطور که فایل رو حذف می کنید و بعد از سطل آشغال برمیگردونید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
داده های فایل روی هارد دیسک هست، داده ها پاک نشده، فقط اسمش از لیست حذف شده، هر زمانی که داده های اون فایل برای استفاده فایل دیگری بازنویسی بشه نیاز به ثبت اش در backup پیش میاد. همانطور که فایل رو حذف می کنید و بعد از سطل آشغال برمیگردونید.

ممنون
اگه منظورتون اینه که بعد از حذف کردن فایل (800 مگ) (کلا shift و delete کردم ها) ، وقتی فایل دیگه ای سر جاش بازنویسی بشه تا حجم بکاپ 800 مگ افزایش پیدا کنه ، من بعد از حذف این فایل ، بیش از 5 گیگ اطلاعات را از یه درایو دیگه داخل اون درایو کپی و پیست کردم اما حجم فایل بکاپ باز فقط اندکی افزایش پیدا کرد و 48 مگ شد (و دوباره از اون فایل بکاپ ، فایل حذف شده را ریکاوری کردم)
 

the_king

مدیرکل انجمن
ممنون
اگه منظورتون اینه که بعد از حذف کردن فایل (800 مگ) (کلا shift و delete کردم ها) ، وقتی فایل دیگه ای سر جاش بازنویسی بشه تا حجم بکاپ 800 مگ افزایش پیدا کنه ، من بعد از حذف این فایل ، بیش از 5 گیگ اطلاعات را از یه درایو دیگه داخل اون درایو کپی و پیست کردم اما حجم فایل بکاپ باز فقط اندکی افزایش پیدا کرد و 48 مگ شد (و دوباره از اون فایل بکاپ ، فایل حذف شده را ریکاوری کردم)
شما که ادعا نمی کنید اون 5 گیگابایت فضای اون 800 مگابایتی رو پوشش داده، میتونه در جای خالی دیگری نوشته شده باشه. اساسا بازیابی داده های به ظاهر حذف شده همینه که داده ها هنوز روی سکتور ها موجوده و تا وقتی بازنویسی نشده امکان بازیابی شون هست.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
شما که ادعا نمی کنید اون 5 گیگابایت فضای اون 800 مگابایتی رو پوشش داده، میتونه در جای خالی دیگری نوشته شده باشه. اساسا بازیابی داده های به ظاهر حذف شده همینه که داده ها هنوز روی سکتور ها موجوده و تا وقتی بازنویسی نشده امکان بازیابی شون هست.

ممنون.
پس با این اوضاع ، اون طرح من برای رصد درایو برای افزایش shadow storage ، منتفی میشه . درسته ؟ راه دیگه ای هم نداره؟

بعد اینکه برای این نرم افزار هم که به اینترنت و کلا شبکه وصل نمیشه هم از دیتابیس sqlite بجای sql server استفاده کنم؟
کلا sql server را فقط توی پروژه هایی که با شبکه ارتباط دارن ، استفاده میکنن؟
ممنون
 

the_king

مدیرکل انجمن
ممنون.
پس با این اوضاع ، اون طرح من برای رصد درایو برای افزایش shadow storage ، منتفی میشه . درسته ؟ راه دیگه ای هم نداره؟
من نظر و استدلال شخصی خودم رو گفتم، اگه چیزی براتون منتفی باشه تصمیم خودتونه. من ایده ای به ذهنم نمیرسه اما اگر راهی برایش پیدا کردید به حرف من که نیست، اجرا می کنید.

بعد اینکه برای این نرم افزار هم که به اینترنت و کلا شبکه وصل نمیشه هم از دیتابیس sqlite بجای sql server استفاده کنم؟
کلا sql server را فقط توی پروژه هایی که با شبکه ارتباط دارن ، استفاده میکنن؟
ممنون
نمیشه گفت فقط، شما هر شیوه و سیستمی رو که برای پایگاه داده بکار ببرید یکسری مزایا و معایب و توانایی ها و قابلیت های خاص خودش رو داره.
بنابر این عاقلانه اش اینه که SQL Server و Oracle و هر سیستم مدیریت پایگاه داده مبتنی بر Client/Server دیگری رو بر اساس نیازتون به پایگاه داده تحت سرور انتخاب کنید.
طبعا نرم افزاری که از شبکه استفاده نکنه، سرور و کلاینتی نداره که پایگاه داده تحت سرور لازم داشته باشه، می توانید SQL Server را انتخاب کنید، اما وقتی شبکه ای در کار نیست، یک انتخاب کاملا نامناسب ئه.
هم از جهت حجم بالای نرم افزارش و هم پیچیدگی و مشکلات نصب و تنظیم و خطاهاش و هم مشکلات سازگاریش با ویندوز های مختلف و یکدهم قابلیت هاش رو هم در محیط بدون شبکه بکار نخواهید برد.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
شما که ادعا نمی کنید اون 5 گیگابایت فضای اون 800 مگابایتی رو پوشش داده، میتونه در جای خالی دیگری نوشته شده باشه. اساسا بازیابی داده های به ظاهر حذف شده همینه که داده ها هنوز روی سکتور ها موجوده و تا وقتی بازنویسی نشده امکان بازیابی شون هست.

بله درسته .
فایل هایی را با حجم 14 گیگ توی درایو گذاشتم و بکاپ افزایشی گرفتم . حجم بکاپ از 48 مگ (که قبلا بود) ، به 97 مگ افزایش پیدا کرد . بعد اون درایو را defragment کردم و دوباره حجمش را دیدم ، به 6.3 گیگ افزایش پیدا کرد .
 

the_king

مدیرکل انجمن
بله درسته .
فایل هایی را با حجم 14 گیگ توی درایو گذاشتم و بکاپ افزایشی گرفتم . حجم بکاپ از 48 مگ (که قبلا بود) ، به 97 مگ افزایش پیدا کرد . بعد اون درایو را defragment کردم و دوباره حجمش را دیدم ، به 6.3 گیگ افزایش پیدا کرد .
کلا در نظر بگیرید که VSS برای پشتیبانگیری از داده های مهم نیست، نه همچین قابلیتی داره و نه برای همچین منظوری طراحی شده. برای همین حجمش اینقدر که برای شما مهمه برای کاربرد های متعارفش همچین مورد مهمی نیست. در اغلب موارد جایی بکار میره که اصلا قرار نیست دائمی حفظ بشه. برای محافظت در مقابل ویروس و باجگیر و آتش سوزی و ... هم مناسب نیست. اگه جایی برای همچین مواردی ازش استفاده شده از تصور اشتباه طراح اون نرم افزاره. اینطور حفاظت های غیر فنی برای کاربر فقط اطمینان کاذب ایجاد می کنه.
 

SU-57

Active Member
سلام

بعضی از سوالات من ارتباطی به برنامه نویسی نداره و من فقط جهت آگاهی خودم می پرسم و اگه بی مورده جواب ندید. کوتاه هم جواب بدید ممنون میشم چون تا قسمت 95 باید مدام سوال بپرسم چون می دونم وقت شما با ارزشه. (کلا این سوالات قسمت 17 هستش)

1- در کد زیر شما گفتی که یک کپی از مقدار 10 ایجاد می شه و در متغیر b قرار می گیره و این یعنی حافظه بیشتری اشغال می شه

کد:
int a = 10;
int b = a;
اما در کلاس ها اشاره گر جایگزین می شه و عمل کپی اتفاق نمی افته.
سوالم اینه که در نهایت اشاره گر هم یک عدده و مقداری از حافظه رو اشغال می کنه. آیا مقدار حافظه ای که اشاره گر اشغال می کنه خیلی کمتر از خود کلاس هستش که حافظه کمتری اشغال بشه

2- این علامت سوال در کد زیر اسم خاصی داره و اصلا چه کاربردی داره که ما باید اینکار رو انجام بدیم که بتونیم مقدار null بهش بدیم.

کد:
int? a = 10;
a = null;
MessageBox.Show(a.ToString());
مثلا چه علامت سوال بزاریم و چه نذاریم مقدار 10 رو نشون میده

کد:
int? a = 10;
int a = 10;
3- گفتی که همه کلاس ها null پذیر هستند اما نمی دونم چرا برای کلاس StringBuilder خطا میده

کد:
StringBuilder a = new StringBuilder("Sajjad");
a = null;
MessageBox.Show(a.ToString());
4- در کدهای زیر این null ها با هم فرق دارن.

کد:
int? b = null;
string c = null;
StringBuilder d = null;
منظورم اینه که چون int عدد می گیره پس null صفره و یک عدده اما برای کلاس ها دیگه مقدار null که صفره یک نوع اشاره گره نه عدد

5- تو کتاب نوشته اگه به متغیری از نوع عدد مقداری اختصاص ندیم کامپایلر خودش مقدار صفر رو به عنوان مقدار اولیه اختصاص میده. اما در کد زیر هیچ مقداری اختصاص نمیده

کد:
int a;
MessageBox.Show(a.ToString());
اما اگه همین int رو آرایه بنویسیم 0 میده

کد:
int[] myNumber = new int[3];
MessageBox.Show(myNumber[0].ToString());
6- مقدار null کدوم از این هاست یعنی دقیقا چه مقداریه چون تو حالت عادی احتمالا رشته خالیه اما تو اشاره گر مقدار صفر در نظر می گیره و به قول شما که این مقدار صفر به حافظه 0 در رم اشاره نمی کنه یعنی میگه اصلا اشاره گری در بین نیست. ولی اگه چنانچه اشاره گر بخواد به خانه صفر در رم اشاره کنه چه عددی رو می گیره؟ آیا همون صفر رو می گیره یا به صورت دیگه ای هست

کد:
null = 0
null = ""







 
آخرین ویرایش:

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام

بعضی از سوالات من ارتباطی به برنامه نویسی نداره و من فقط جهت آگاهی خودم می پرسم و اگه بی مورده جواب ندید. کوتاه هم جواب بدید ممنون میشم چون تا قسمت 95 باید مدام سوال بپرسم چون می دونم وقت شما با ارزشه. (کلا این سوالات قسمت 17 هستش)

1- در کد زیر شما گفتی که یک کپی از مقدار 10 ایجاد می شه و در متغیر b قرار می گیره و این یعنی حافظه بیشتری اشغال می شه

کد:
int a = 10;
int b = a;
اما در کلاس ها اشاره گر جایگزین می شه و عمل کپی اتفاق نمی افته.
سوالم اینه که در نهایت اشاره گر هم یک عدده و مقداری از حافظه رو اشغال می کنه. آیا مقدار حافظه ای که اشاره گر اشغال می کنه خیلی کمتر از خود کلاس هستش که حافظه کمتری اشغال بشه

2- این علامت سوال در کد زیر اسم خاصی داره و اصلا چه کاربردی داره که ما باید اینکار رو انجام بدیم که بتونیم مقدار null بهش بدیم.

کد:
int? a = 10;
a = null;
MessageBox.Show(a.ToString());
مثلا چه علامت سوال بزاریم و چه نذاریم مقدار 10 رو نشون میده

کد:
int? a = 10;
int a = 10;
3- گفتی که همه کلاس ها null پذیر هستند اما نمی دونم چرا برای کلاس StringBuilder خطا میده

کد:
StringBuilder a = new StringBuilder("Sajjad");
a = null;
MessageBox.Show(a.ToString());
4- در کدهای زیر این null ها با هم فرق دارن.

کد:
int? b = null;
string c = null;
StringBuilder d = null;
منظورم اینه که چون int عدد می گیره پس null صفره و یک عدده اما برای کلاس ها دیگه مقدار null که صفره یک نوع اشاره گره نه عدد

5- تو کتاب نوشته اگه به متغیری از نوع عدد مقداری اختصاص ندیم کامپایلر خودش مقدار صفر رو به عنوان مقدار اولیه اختصاص میده. اما در کد زیر هیچ مقداری اختصاص نمیده

کد:
int a;
MessageBox.Show(a.ToString());
اما اگه همین int رو آرایه بنویسیم 0 میده

کد:
int[] myNumber = new int[3];
MessageBox.Show(myNumber[0].ToString());
6- مقدار null کدوم از این هاست یعنی دقیقا چه مقداریه چون تو حالت عادی احتمالا رشته خالیه اما تو اشاره گر مقدار صفر در نظر می گیره و به قول شما که این مقدار صفر به حافظه 0 در رم اشاره نمی کنه یعنی میگه اصلا اشاره گری در بین نیست. ولی اگه چنانچه اشاره گر بخواد به خانه صفر در رم اشاره کنه چه عددی رو می گیره؟ آیا همون صفر رو می گیره یا به صورت دیگه ای هست

کد:
null = 0
null = ""









سلام آقا رامین .
1) مقداری که برای هر متغییر اشغال میشه (چه استراکچر چه کلاس و ...) و البته بجز استراکچرهای built in (مثل int و double و short و ... که اندازه شون مشخص اند) ، به نوع 32 بیت بودن یا 64 بیت بودن اون برنامه بستگی داره (32 یا 64 بیت بودن خود برنامه ها هم که به ویندوز میتونه بستگی داشته باشه) . منظورم اندازه ی شی نیست ها .
اگه برنامه 32 بیتی باشه ، اندازه ی متغییر 32 بیت خواهد بود و در برنامه های 64 بیت ، اندازه ی متغییرشون 64 بیت هه .
خوب در متغییرها با نوع های value type ها (مثل استراکچر) ، که اندازه ی شی اش هم همین 32 یا 64 بیت خواهد بود . در متغییرها با نوع های reference type ، هر چند اندازه ی متغییر (که اشاره گر به آدرس حافظه ی اون شی هستن) ، 32 یا 64 بیت خواهد بود اما اندازه ی شی شون متفاوت هه . اندازه ی شی ، باز خودش بستگی به اعضای اون چیز (مثلا بستگی به اعضای فیلد یا بقیه ی اعضای اون کلاس یا استراکچر یا ...) داره که هر عضو ، باز اندازه ی خاص خودش را میتونه داشته باشه. مثلا فرض کنید

کد:
    public class Test_1
    {
        int a = 10;
        Test_2 b = new Test_2();
    }

    public class Test_2
    {
        int a = 10;
    }
---------------------------------------------

        private void button7_Click(object sender, EventArgs e)
        {
            Test_1 test1 = new Test_1();
        }

در رویداد button7_Click ، اندازه ی متغییر test1 ، به 32 یا 64 بیتی بودن این برنامه بستگی داره که فعلا نمیدونیم چیه (فرض میکنیم برنامه اش 32 بیتی باشه پس اندازه ی متغییر اش 32 بیتی هه) که اشاره گری به شی کلاس Test_1 هست . حالا شی کلاس Test_1 ، یه متغییر a از نوع int هست که چون از نوع استراکچرهای built in هست ، 32 بیت هست . یه متغییر b از نوع Test_2 داره ، که اولا چون برنامه مون 32 بیتی هست ، اندازه ی متغییر اش 32 بیت هست و دوما اندازه ی شی اش مثل همین روال ، به اندازه ی اعضای کلاس Test_2 بستگی خواهد داشت .
حالا اگه اشتباه نکنم ، اندازه ی یک کلاس (یا استراکچر و ایناها) ، فقط بستگی به اندازه ی متغییرهاشون دارن (نه شی شون) . یعنی اندازه ی کلاس Test_1 ، احتمالا 64 بیت در برنامه ی 32 بیتی باید باشه (32 بیت برای متغییر a و 32 بیت برای متغییر b اش) .
حالا استاد علی باید تایید کنه .

2) کاربردش کلا زمانی هه که از ما اعدادی بخوان که بجای مقدار ، null هم بخوایم بدیم . هر چند خیلی خیلی کمه ، ولی گاها بسیار تک و توک پیش میاد . بیشتر زمان ارتباط برقرار کردن با api های ویندوز شاید اونم تک و توک پیش بیاد .
خوب شما مقدار 10 را دادین . باید هم 10 را نشون بده دیگه .

3) خوب شما بعد از مقداردهی StringBuilder ، مقدار null را دادین دیگه . مقدار null که قابل نمایش نیست . وقتی مقداری را null بدین ، ارور System.NullReferenceException را پرتاب میکنه . (البته نمیدونم چرا برای من در یه حالاتی ، برای مقدار null ارور پرتاب نمیکنه و خالی نمایش میده)

4) اشاره گر هم نوعی عدد هه . null هم بله صفر هه . چه برای نوع های عددی مثل int و چه برای نوع های کلاس هاس های دیگه و ... .

5) نمیدونم کتاب ها چرا جمله ی کامل را نمیگن . توی کتاب منم همین نوشته بود :green: . جمله اش درسته ولی کامل نیست .
وقتی یه متغییر میگیرید (بدون در نظر گرفتن مقدار یا همون شی اش) مثل

کد:
int a;

اندازه ای که در بالا گفتم ، بهش اختصاص پیدا میکنه (32 بیت) . اما این متغییر ممکنه از بیت هایی که قبلا برنامه ی دیگه ای ازش استفاده کرده بودش و مقداردهی اش کرده بود (فرض میکنیم مقدار 100 گذاشته بود) و بعد آزادش کرده بود ، گرفته شده باشه .یعنی مقداری ناخواسته . یعنی تا اینجا ، با اونکه شما فقط متغییری را تعریف کردید و بهش مقداری ندادید ، مقدار ناخواسته ی 100 (یا هر مقداری) که از برنامه ی قبلی ازش استفاده کرد و پر اش کرد ، را داره .
حالا وقتی این متغییر a ، متغییر سراسری بوده باشه ، مقدار پیش فرض اش را توی خونه هاش جایگزین میکنه که کلا مقدار پیش فرض ، همون صفر هه (چه null باشه که همون 0 هه . چه اعداد باشن که بازم صفر اند و چه بولین باشه که false و false هم همون 0 هه) .
اما وقتی این متغییر a ، متغییر محلی باشه ، این مقدار پیش فرض براش در نظر گرفته نمیشه و صرفا همون مقدار ناخواسته ای که از حافظه ی قبلی ای که داده شده بود (مقدار 100) توش هست . بنابراین سی شارپ نمیذاره متغییرهای محلی ، بدون مقداردهی برنامه نویس ، فراخونی بشه .
این موضوع (شماره ی 5) ، را استاد علی قبلا توضیح داده بودن و توی قسمت 30 گفته شد .
 

the_king

مدیرکل انجمن
1- در کد زیر شما گفتی که یک کپی از مقدار 10 ایجاد می شه و در متغیر b قرار می گیره و این یعنی حافظه بیشتری اشغال می شه

کد:
int a = 10;
int b = a;
اما در کلاس ها اشاره گر جایگزین می شه و عمل کپی اتفاق نمی افته.
سوالم اینه که در نهایت اشاره گر هم یک عدده و مقداری از حافظه رو اشغال می کنه. آیا مقدار حافظه ای که اشاره گر اشغال می کنه خیلی کمتر از خود کلاس هستش که حافظه کمتری اشغال بشه
بله، حافظه خیلی کمتر و البته با اندازه ثابتی اشغال می کنه که همه اشاره گر ها همون اندازه یکسان رو دارند. مثلا شیء میتونه 500 بایت حجم داشته باشه ولی اشاره گر فقط 4 یا 8 بایته.

2- این علامت سوال در کد زیر اسم خاصی داره و اصلا چه کاربردی داره که ما باید اینکار رو انجام بدیم که بتونیم مقدار null بهش بدیم.

کد:
int? a = 10;
a = null;
MessageBox.Show(a.ToString());
مثلا چه علامت سوال بزاریم و چه نذاریم مقدار 10 رو نشون میده
اسمش Nullable ئه، تمامی انواع داده هایی که در حالت عادی null نمی پذیرند رو Nullable می کنیم تا بشه بهشون مقدار null رو هم نسبت داد. فرضا int ها. مثال از کاربرد اش اینه که از کاربر می خواهید یک فرم کنکور چهار گزینه ای رو پر کنه که پاسخ به گزینه ها اختیاریه. برای هر گزینه null یعنی بهش پاسخی داده نشده و مقدار 0 یعنی پاسخ مخدوشه (فرضا دو گزینه رو همزمان تیک زده) و مقادیر 1 و 2 و 3 و 4 یعنی پاسخ یکی از گزینه های چهار گانه است.

Nullable در حقیقت یک struct ئه، ساختاره، که به دور اون نوع داده اصلی کشیده میشه. داده اصلی سر جاشه، اگه 10 باشه همچنان 10 میمونه چون int هیچوقت نمیتونه null بشه. Nullable در کنارش یک فیلد وضعیتی اضافه می کنه که بگه null هست یا نیست، به خود داده دست نمی زنه. از اونجایی که ToString معادلی برای null نداره، به داده اصلی ارجاع داده شده، این دلیل بر این نیست که Nullable تاثیری نداره.

3- گفتی که همه کلاس ها null پذیر هستند اما نمی دونم چرا برای کلاس StringBuilder خطا میده

کد:
StringBuilder a = new StringBuilder("Sajjad");
a = null;
MessageBox.Show(a.ToString());
خطا ربطی به اینکه از نوع کلاس StringBuilder هست یا هر کلاس دیگری نداره، هر کلاس دیگری هم بود همین مساله صادق بود. خطا برای اینه که برای مقدار null متد ToString رو اجرا می کنید. null یعنی هیچی. هیچی که وجود نداره که ToString برایش اجرا بشه. null متعلق به هیچ کلاس یا نوع داده خاصی نیست، وجودی نداره که بگید این null از نوع کلاس StringBuilder بوده.

4- در کدهای زیر این null ها با هم فرق دارن.

کد:
int? b = null;
string c = null;
StringBuilder d = null;
منظورم اینه که چون int عدد می گیره پس null صفره و یک عدده اما برای کلاس ها دیگه مقدار null که صفره یک نوع اشاره گره نه عدد
null هیچوقت عدد نیست و هیچوقت هم معادل 0 نیست. اما در مورد مقدار null فرقی نداره که منبعش چیه، null از هر متغیری که باشه یکسانه و تفاوتی بین null ای که از string بیاد یا StringBuilder نیست. اما اون ?int غیر از مقدار null یک فیلد مقداری int هم داره که چون مقدار پیشفرضش تغییری نکرده 0 ئه. که خودشو در جاهایی مثل ToString نشون میده. Nullable واقعا باعث نمیشه که int توانایی قبول کردن null رو پیدا کنه، رفتار یک نوع داده null پذیر رو شبیه سازی می کنه.

5- تو کتاب نوشته اگه به متغیری از نوع عدد مقداری اختصاص ندیم کامپایلر خودش مقدار صفر رو به عنوان مقدار اولیه اختصاص میده. اما در کد زیر هیچ مقداری اختصاص نمیده

کد:
int a;
MessageBox.Show(a.ToString());
اما اگه همین int رو آرایه بنویسیم 0 میده

کد:
int[] myNumber = new int[3];
MessageBox.Show(myNumber[0].ToString());

قبلا در موردش مفصل توضیح داده شده، در نظر بگیرید که کامپایلر ازتون خطا میگیره که چرا قبل از مقدار دهی متغیر محلی دارید ازش مقدار میخوانید. نمیگه که نمیتوانم بهش مقدار اولیه اختصاص بدم، اگه میخواست میتونست بهش مقدار اولیه اختصاص بده ولی بر اساس منطق طراحش اینکار رو نمی کنه. وادارتون میکنه که برای متغیر های محلی اول مقدار اولیه در نظر بگیرید و بعد بخوانید. اون [new int[3 هم مثالی از مقدار دهی اولیه است. خونه های اون آرایه متغیر محلی نیستند که وادارتون کنه برای دونه دونه خونه ها مقدار اولیه ثبت کنید.


6- مقدار null کدوم از این هاست یعنی دقیقا چه مقداریه چون تو حالت عادی احتمالا رشته خالیه اما تو اشاره گر مقدار صفر در نظر می گیره و به قول شما که این مقدار صفر به حافظه 0 در رم اشاره نمی کنه یعنی میگه اصلا اشاره گری در بین نیست. ولی اگه چنانچه اشاره گر بخواد به خانه صفر در رم اشاره کنه چه عددی رو می گیره؟ آیا همون صفر رو می گیره یا به صورت دیگه ای هست

کد:
null = 0
null = ""
در زبان #C هیچکدوم معادل null نیست، نه صفر ئه و نه string.Empty ئه. string.Empty همون "" ئه.
مقدار 0 که یک داده عددی است و "" هم که برای خودش یک شیء مستقل ئه از نوع string. اما null دقیقا یعنی هیچی. داده و شیء نیست. اشاره گری که به جایی اشاره نکنه عملا وجود نداره، چون اشاره گر یک عدد ئه و عدد هم null شدنی نیست. در تعاریف ویندوز NULL رو با مقدار 0 معادل در نظر میگیرند، یعنی اشاره گری که NULL باشه به خونه 0 حافظه اشاره می کنه، چیزی که در #C معادلش IntPtr.Zero ئه و در ارتباط با محیط خارج از زبان معنی داره.
اما این چیزی نیست که شما در داخل زبان #C درگیرش باشید، شما null رو با null میشناسید، معادل عددی و رشته ای برایش پیدا نمی کنید.
 

SU-57

Active Member
در زبان #C هیچکدوم معادل null نیست، نه صفر ئه و نه string.Empty ئه. string.Empty همون "" ئه.
مقدار 0 که یک داده عددی است و "" هم که برای خودش یک شیء مستقل ئه از نوع string. اما null دقیقا یعنی هیچی. داده و شیء نیست.

ممنونم استاد

1- در کدهای زیر:

کد:
 int a = 10;

string b = "Ali";
در فیلم گفته شد که عدد 10 و رشته Ali هر دو شی هستند اما شما فرمودین که 10 یک داده است


2- در کدهای زیر:

کد:
string[] myString = new string[3];
MessageBox.Show(myString[0]);

char[] myString = new char[3];
MessageBox.Show(myString[0].ToString());
الان توی پنجره دیالوگ null نمایش داده می شه یا رشته خالی ""

3- یک مبحث قدیمی:

شما فرموردین که در نوع decimal ممیز ثابت یک طول مشخص برای ارقام صحیح و یک طول مشخص برای ارقام اعشاری داره. آیا طول این ها مشخص هست که برای هر قسمت مثلا چند بایته؟
همچنین فرمودین که در ممیز شناور اگه مقدار مورد نظر از مقدار حافظه بیشتر باشه اون ارقام رو حذف می کنه و به جاش صفر در نظر می گیره. سوالم اینه که:
الف) اگه اون ارقام رو حذف می کنه چطور به جاش مقدار صفر در نظر می گیره؟
ب) در نوع داده ای decimal اگه ارقام صحیح و ارقام اعشاری از اون طولی که براش مشخص شده بیشتر بشن مثل ممیز شناور حذف میشن.

همچنین در صفحه 22 فرمودین که:

"در عددی مثل 1002400000 یا 10.024 یا 0.0000100240 صرفا 10024 اش با ارزش ئه و بقیه اش صرفا رقم های بی ارزش 0 ئه"

ولی به نظر من صفرهای جلوی 1002400000 و همچنین صفرهای پشت 0.0000100240 با ارزش هستند چون با حذف اون ها عدد عوض می شه.

4- مقدار داده ای که نوع int می گیره مشخصه. من می خوام حفظ بکنم مثلا میگم از منفی 2 میلیارد تا مثبت 2 میلیارد اما مقدار بعضی از انواع داده ای برای من مبهمه مثل float و double. چطوری می شه اینا رو به یک عددی تبدیل کرد که قابل حفظ کردن باشه به صورت تقریبی

______________________________________________________

سجاد جان من روی اون کدی که دادی و نوشته هات باید بیشتر فکر کنم چون برام مبهمه و باید فکر کنم ببینم دقیقا چی گفتی و یک مقدار با کدها درگیر بشم و اگه سوالی بود می پرسم.
نکته دیگه اینکه اگه شما کد ها رو اونطوری بدی من بلد نیستم جایگزاری کنم اگه می شه پروژه اون رو بزار. اما اگه همه توی یک رویداد داخل button باشن مشکلی ندارم.
 

the_king

مدیرکل انجمن
ممنونم استاد

1- در کدهای زیر:

کد:
 int a = 10;

string b = "Ali";
در فیلم گفته شد که عدد 10 و رشته Ali هر دو شی هستند اما شما فرمودین که 10 یک داده است
مثل اینه که بگین پرتقال میوه است یا گیاه. هر دو درسته. 10 هم داده (data) است و هم شیء (object). هر متغیری از هر نوع داده ای که باشه مقداری که داخلش قرار می گیره یک داده است.
در #C هم تمامی انواع داده ای عبارتند از object و بقیه که از object وراثت دارند، نوع داده ای وجود نداره که object نباشه.

2- در کدهای زیر:

کد:
string[] myString = new string[3];
MessageBox.Show(myString[0]);

char[] myString = new char[3];
MessageBox.Show(myString[0].ToString());
الان توی پنجره دیالوگ null نمایش داده می شه یا رشته خالی ""
null نمایش داده میشه چون مقدار پیشفرض string ها و سایر انواع داده ای که null پذیر هستند، null ئه، رشته تهی "" مقدار پیشفرض string ها نیست. می توانید این مورد را در اجرا بررسی کنید :
کد:
            string[] myString = new string[3];
            if (myString[0] == null)
            {
                MessageBox.Show("null");
            }
            else if (myString[0] == "")
            {
                MessageBox.Show("empty string");
            }


3- یک مبحث قدیمی:

شما فرموردین که در نوع decimal ممیز ثابت یک طول مشخص برای ارقام صحیح و یک طول مشخص برای ارقام اعشاری داره. آیا طول این ها مشخص هست که برای هر قسمت مثلا چند بایته؟
نه اشتباه نکنید، طولی که برای ارقام اعشاری و صحیح در نظر گرفته جدا و مستقل از هم نیست، کنار هم و ترکیبی ئه، طول مشخصی برای کلیه ارقام ارزشمند داره، اعم از اینکه رقم ها صحیح یا اعشاری باشند، ممیز رو در هر جایی میان اون رقم ها میتونه قرار بده. اما مثل ممیز شناور گرد کردنی در کار نیست یا حداقل به اون شدت نیست. ارزشمند از این لحاظ که در عدد 120.45000 اون سه 000 رقم های ارزشمندی نیستند و بود و نبودشون موثر نیست.
decimal یک نوع داده 128 بیتی ئه، اما از اونجایی که ما طول رو با رقم های مبنای 10 میسنجیم و نه مبنای 2، طولش در مبنای 10 تخمینی میشه، چیزی بین 28 الی 29 رقم مبنای 10 میشه.
یعنی یک عدد که حداکثر 28 رقم ارزشمند داره، اعم از اینکه رقم ها قبل یا بعد از ممیز باشند به خوبی و بدون کوچکترین گرد شدنی داخل decimal جا میگیره.

همچنین فرمودین که در ممیز شناور اگه مقدار مورد نظر از مقدار حافظه بیشتر باشه اون ارقام رو حذف می کنه و به جاش صفر در نظر می گیره. سوالم اینه که:
الف) اگه اون ارقام رو حذف می کنه چطور به جاش مقدار صفر در نظر می گیره؟
حذف کردن باید به شکلی انجام بشه که عددی که ثبت میشه حداکثر نزدیکی رو به عدد اولیه داشته باشه، برای اینکه رقم هایی که کمترین ارزش رو دارند با صفر شدن فدا میشن، از ارزش می افتند. وقتی صفر شد و دیگه ارزشمند نشد حذف میشه. یک مثال ابتدایی میزنم از نوع داده float که دقت نگهداریش در حد 7 رقمه، نمی تونه اعدادی مثل 123456789 و 0.123456789 و ... رو دقیق ثبت کنه. مجبوره رقم های کم ارزشترش رو صفر کنه تا از ارزش بیافته و قابل ذخیره شدن بشه :
کد:
            float a = 123456789F;
            float b = 0.123456789F;
            float c = a + b;
            string format = "0.0###############";
            MessageBox.Show(string.Format("a = {0:" + format + "}\n"
                + "b = {1:" + format + "}\n"
                + "c = {2:" + format + "}", a, b, c));
            ;
حالا ببینید همون ممیز شناور در float که فقط توانایی نگهداری 7 رقم ارزشمند رو داره چقدر خوب میتونه ارقام خیلی بزرگ یا کوچکی رو نگهداری کنه :
کد:
            float a = 123000000000000000F;
            float b = 0.0000000000000123F;
            float c = a + b;
            string format = "0.0###############";
            MessageBox.Show(string.Format("a = {0:" + format + "}\n"
                + "b = {1:" + format + "}\n"
                + "c = {2:" + format + "}", a, b, c));
            ;
اون صفر های ابتدا و انتها در رقم های a و b برای ممیز شناور رقم های ارزشمندی نیستند، برای همینه که float میتونه اینقدر محدوده عددی بزرگی رو پوشش بده.
و توجه کنید که در مقدار c اون رقم های 0 میانی ارزشمند ئه، برای همینه که در مورد c ناچار به صفر شدن کلیه رقم های بعد از ممیز میشه و با اینکه c مجموع a و b بوده؛ خبری از رقم های b نیست و مقدارش مثل a میشه و ارقام ارزشمند b با صفر شدن فدا شدن.این مثال نشون میده که شما از float می توانید توقع نگهداری عدد بزرگی مثل 123000000000000 یا عدد کوچکی مثل 0.00000000000123 رو داشته باشید، اما اون صفر ها در ابتدا و انتها برای ممیز شناور رقم های ارزشمندی نیستند.

ب) در نوع داده ای decimal اگه ارقام صحیح و ارقام اعشاری از اون طولی که براش مشخص شده بیشتر بشن مثل ممیز شناور حذف میشن.
الزاما نه، برای رقم های اعشاری میتوانید همچین تصوری داشته باشید ولی وقتی عدد به قدری بزرگ یا کوچک شد که در ظرفیت اش نگنجید با خطا متوقف میشه.

همچنین در صفحه 22 فرمودین که:

"در عددی مثل 1002400000 یا 10.024 یا 0.0000100240 صرفا 10024 اش با ارزش ئه و بقیه اش صرفا رقم های بی ارزش 0 ئه"

ولی به نظر من صفرهای جلوی 1002400000 و همچنین صفرهای پشت 0.0000100240 با ارزش هستند چون با حذف اون ها عدد عوض می شه.
قطعا موثر هستند ولی برای نگهداری رقم با ارزشی نیستند، تعداد اون صفر ها مهمه، به عبارت دیگه محل ممیز مهمه، نه رقم های صفر اینور و اونور. در سیستم محاسبات اعشاری برای نگهداری تعداد اون رقم های صفر جایگاه ویژه و مستقلی هست که بصورت مضرب توانی از 10 نگهداریش می کنه. فرضا 123 رو به همراه 5 نگهداری می کنه که اون 5 یعنی 10 به توان 5 یا 5 تا صفر یا 00000. پس نادیده گرفته نمیشن، اما خود رقم های صفر اینور و اونور ثبت نمیشن.

4- مقدار داده ای که نوع int می گیره مشخصه. من می خوام حفظ بکنم مثلا میگم از منفی 2 میلیارد تا مثبت 2 میلیارد اما مقدار بعضی از انواع داده ای برای من مبهمه مثل float و double. چطوری می شه اینا رو به یک عددی تبدیل کرد که قابل حفظ کردن باشه به صورت تقریبی
خیلی ساده است، گو اینکه حفظ کردنی نیست. به جدول تقریبی محدوده شون یک نگاهی بندازید :
Floating-point types table - C# Reference
در نظر بگیرید که محدودها مثبت و منفی دارند، یعنی بجای دو مرز بزرگ و کوچیک، چهار تا مرز داریم. دلیلش اینه که بین اعدادی که خیلی ریز و کسری هستند و اعداد خیلی بزرگ و درشت تفاوت هست، مثال float رو ببینید :
datatypes.jpg
عدد مثبتی که خیلی خیلی بزرگه مثل 3.4 ضربدر 10 به توان 38 که معادل یک 34 ای میشه که جلوش 37 تا صفر بگذارید.
عدد مثبتی که با وجود مثبت بودن خیلی کسری و کوچیکه و به صفر فوق العاده نزدیکه، مثل 1.5 ضربدر 10 به توان 45- که معادل یک 0.15 ای میشه که میان . و 1 اش 44 تا صفر بگذارید.
عدد منفی ای که خیلی خیلی درشت ئه مثل 3.4- ضربدر 10 به توان 38 که معادل یک 34- ای میشه که جلوش 37 تا صفر بگذارید.
و عدد منفی ای که خیلی خیلی کسری و فوق العاده به صفر نزدیکه، مثل 1.5- ضربدر 10 به توان 45- که معادل یک 0.15- ای میشه که میان . و 1 اش 44 تا صفر بگذارید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد
استاد علی انگار بکاپ افزایشی و تفاوتی اش داستان داره .
برای این نوع های بکاپ ، به عضو IVssComponent::GetBackupStamp احتیاج هست . بنابراین به ساخت شی از اینترفیس IVssComponent احتیاج هست . متد IVssWriterComponents::GetComponent ، این شی را ایجاد میکنه .
در کد زیر :


کد:
            IVssImplementation vssImplementation = VssUtils.LoadImplementation();
            using (IVssBackupComponents vssBackup = vssImplementation.CreateVssBackupComponents())  
            {
                vssBackup.InitializeForBackup(null);

                vssBackup.SetBackupState(false, false, VssBackupType.Incremental, false);
                vssBackup.GatherWriterMetadata();
                vssBackup.SetContext(VssSnapshotContext.ClientAccessibleWriters);



                IList<IVssWriterComponents> vssWriterComponents = vssBackup.WriterComponents;
                foreach (var writerComponent in vssWriterComponents)
                {
                    IList<IVssComponent> components = writerComponent.Components;
                }

            }

در alphavss هم IVssWriterComponents.Components کار متد IVssWriterComponents::GetComponent را میکنه.
ولی مقدار متغییر components ، نال هه .
 

the_king

مدیرکل انجمن
سلامی مجدد
استاد علی انگار بکاپ افزایشی و تفاوتی اش داستان داره .
برای این نوع های بکاپ ، به عضو IVssComponent::GetBackupStamp احتیاج هست . بنابراین به ساخت شی از اینترفیس IVssComponent احتیاج هست . متد IVssWriterComponents::GetComponent ، این شی را ایجاد میکنه .
در کد زیر :


کد:
            IVssImplementation vssImplementation = VssUtils.LoadImplementation();
            using (IVssBackupComponents vssBackup = vssImplementation.CreateVssBackupComponents()) 
            {
                vssBackup.InitializeForBackup(null);

                vssBackup.SetBackupState(false, false, VssBackupType.Incremental, false);
                vssBackup.GatherWriterMetadata();
                vssBackup.SetContext(VssSnapshotContext.ClientAccessibleWriters);



                IList<IVssWriterComponents> vssWriterComponents = vssBackup.WriterComponents;
                foreach (var writerComponent in vssWriterComponents)
                {
                    IList<IVssComponent> components = writerComponent.Components;
                }

            }

در alphavss هم IVssWriterComponents.Components کار متد IVssWriterComponents::GetComponent را میکنه.
ولی مقدار متغییر components ، نال هه .
به نظر نمیاد null باشه، به نظر میاد که vssWriterComponents عضوی نداشته باشه. منطقیه. vssBackup هیچ اطلاعی از داده که میخواهید ازش backup از نوع Incremental بگیرید نداره.
بر چه اساسی می توانست سر خود یک Writer انتخاب کنه؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
به نظر نمیاد null باشه، به نظر میاد که vssWriterComponents عضوی نداشته باشه. منطقیه. vssBackup هیچ اطلاعی از داده که میخواهید ازش backup از نوع Incremental بگیرید نداره.
بر چه اساسی می توانست سر خود یک Writer انتخاب کنه؟

ممنون
داده که هنوز ازش بکاپ نگرفتیم .
پس باید قبل از اینها و این کد ، writer مون را مشخص کنیم؟
لیست رایترها را میدونم چجوری میگیرن . انگار هم میدونم کدوم رایتر را هم باید انتخاب کنم. ولی نمیدونم چجوری رایتر مورد نظرم را براش ست کنم و بهش بشناسونم؟
 

the_king

مدیرکل انجمن
ممنون
داده که هنوز ازش بکاپ نگرفتیم .
پس باید قبل از اینها و این کد ، writer مون را مشخص کنیم؟
لیست رایترها را میدونم چجوری میگیرن . انگار هم میدونم کدوم رایتر را هم باید انتخاب کنم. ولی نمیدونم چجوری رایتر مورد نظرم را براش ست کنم و بهش بشناسونم؟
نه. مطمئن نیستم چون دارم بر اساس چیزی که شما میگید نظر میدم. اگر نیاز به Timestamp دارید باید مربوط به backup قبلی باشه. یعنی چون شما دارید بر اساس یک Snapshot قبلی نسخه جدیدی تهیه می کنید با QuerySnapshots لیست شون رو میگیرید و اون Snapshot مورد نظر رو بین شون پیدا می کنید که خودش CreationTimestamp داره، یعنی writer اش در اون مشخصه و نیازی نیست writer ای اضافه کنید یا ایجاد کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنونم استاد علی
من این صفحه :

Requester Role in VSS Incremental and Differential Backups - Windows applications

و اندکی هم این صفحه رو خوندم :

Requester Role in Backing Up Complex Stores - Windows applications

اما بصورت نسبی متوجه شدم چی میگه . یعنی دقیق متوجه نشدم . یه پاراگراف را معمولا خوب توضیح میده اما ارتباط پاراگراف های متفاوت ، کمی گیج کننده هست .
برای گرفتن بکاپ افزایشی و تفاوتی ، اولین مقاله مهم تره یا دومی؟ مباحث اش شبیه هم هست .
در اولی گفت ، برای بکاپ افزایشی و تفاوتی ، باید این 4 مرحله را برین :

1) مشخص کردن اینکه چه سطحی از ساپورت writer ها در دسترس هست (با IVssBackupComponents::GetWriterMetadata) مخصوصا اینکه مشخص کنید چه backup schema ساپورت میشود (توسط IVssExamineWriterMetadata::GetBackupSchema) (کافیه که رایتری مقدار VSS_BS_INCREMENTAL یا VSS_BS_DIFFERENTIAL یا هر دو را پشتیبانی کنه. اگه رایتری مقدارVSS_BS_EXCLUSIVE_INCREMENTAL_DIFFERENTIAL را پشتیبانی کنه ، یعنی در یکی از حالت های بکاپ افزایشی یا تفاوتی میتونه شرکت کنه و محدود خواهد بود به یکی از این دو بکاپ)
2) یک backup state مناسب انتخاب کنیم (توسط متد IVssBackupComponents::SetBackupState و در پارامتر backupType ، نوع بکاپ مثلا افزایشی یا تفاوتی یا کامل را انتخاب کنیم)
3) مشخصات file set و file را برای بکاپ افزایشی و تفاوتی بدست بیاریم .
4) بکاپ را اجرا کنیم (توسط متد IVssBackupComponents.DoSnapshotSet)

-------------------------------------------------

الان اینهایی که گفتم درسته؟ همین کارها را باید کنم؟
من شماره ی 3 را متوجه نشدم چی میگه و چی میخواد دقیقا.
اما در مقاله ی دوم (و همینطور آخرای مقاله ی اول) ، بیشتر سر این بحث میکنه که برای ایجاد بکاپ های افزایشی و تفاوتی ، نیاز به ارتباط و گره زدن بکاپ فعلی به بکاپ قبلی داریم و این ارتباط را با متد IVssBackupComponents::SetPreviousBackupStamp میشه انجام داد .
اما همونطور که گفتم ، رابطه ی این متد با بحث بالایی (که 4 قسمت داشت) را نفهمیدم و خوب توضیح نداد .
الان دقیقا برای بکاپ افزایشی و تفاوتی ، چه مراحلی را باید طی کنم؟ همون 4 تای بالا کافی هه؟
 

the_king

مدیرکل انجمن
خیلی ممنونم استاد علی
من این صفحه :

Requester Role in VSS Incremental and Differential Backups - Windows applications

و اندکی هم این صفحه رو خوندم :

Requester Role in Backing Up Complex Stores - Windows applications

اما بصورت نسبی متوجه شدم چی میگه . یعنی دقیق متوجه نشدم . یه پاراگراف را معمولا خوب توضیح میده اما ارتباط پاراگراف های متفاوت ، کمی گیج کننده هست .
برای گرفتن بکاپ افزایشی و تفاوتی ، اولین مقاله مهم تره یا دومی؟ مباحث اش شبیه هم هست .
در اولی گفت ، برای بکاپ افزایشی و تفاوتی ، باید این 4 مرحله را برین :

1) مشخص کردن اینکه چه سطحی از ساپورت writer ها در دسترس هست (با IVssBackupComponents::GetWriterMetadata) مخصوصا اینکه مشخص کنید چه backup schema ساپورت میشود (توسط IVssExamineWriterMetadata::GetBackupSchema) (کافیه که رایتری مقدار VSS_BS_INCREMENTAL یا VSS_BS_DIFFERENTIAL یا هر دو را پشتیبانی کنه. اگه رایتری مقدارVSS_BS_EXCLUSIVE_INCREMENTAL_DIFFERENTIAL را پشتیبانی کنه ، یعنی در یکی از حالت های بکاپ افزایشی یا تفاوتی میتونه شرکت کنه و محدود خواهد بود به یکی از این دو بکاپ)
2) یک backup state مناسب انتخاب کنیم (توسط متد IVssBackupComponents::SetBackupState و در پارامتر backupType ، نوع بکاپ مثلا افزایشی یا تفاوتی یا کامل را انتخاب کنیم)
3) مشخصات file set و file را برای بکاپ افزایشی و تفاوتی بدست بیاریم .
4) بکاپ را اجرا کنیم (توسط متد IVssBackupComponents.DoSnapshotSet)

-------------------------------------------------

الان اینهایی که گفتم درسته؟ همین کارها را باید کنم؟
من شماره ی 3 را متوجه نشدم چی میگه و چی میخواد دقیقا.
اما در مقاله ی دوم (و همینطور آخرای مقاله ی اول) ، بیشتر سر این بحث میکنه که برای ایجاد بکاپ های افزایشی و تفاوتی ، نیاز به ارتباط و گره زدن بکاپ فعلی به بکاپ قبلی داریم و این ارتباط را با متد IVssBackupComponents::SetPreviousBackupStamp میشه انجام داد .
اما همونطور که گفتم ، رابطه ی این متد با بحث بالایی (که 4 قسمت داشت) را نفهمیدم و خوب توضیح نداد .
الان دقیقا برای بکاپ افزایشی و تفاوتی ، چه مراحلی را باید طی کنم؟ همون 4 تای بالا کافی هه؟
الان با Complex Stores کاری ندارید، مگر اینکه این توانایی رو دارید که بدون فهمیدن مطالب مقدماتی بتوانید مطالب پیچیده تر رو متوجه بشید.
توضیحاتش نقصی نداره، خیلی خوب توضیح داده. اما برای کسی که مباحث قبلی رو خوب مطالعه کرده. طبعا اگه مباحث قبلی رو کامل متوجه نشده باشید بعدی ها رو هم متوجه نخواهید شد. مثل اینه که کسی کتاب آموزش سطح پیشرفته Microsoft Word رو بخونه در حالی که کار با کامپیوتر و ویندوز رو بلد نباشه. طبعا درست متوجه نمیشه، ولی نه به این دلیل که کتاب خوب توضیح نداده، به این خاطر که Copy/Paste و فایل و فولدر و درایو و فونت... برایش مفاهیم آشنایی نیستند. هر مطلبی رو که متوجه نشدید از رویش رد شدید و گفتید مطلب بدرد بخوری نداشت. خوب معلومه که اینطوری در درک مطالب بعدی به مشکل برمیخورید.

مورد اول هم مقدمات کار ئه، بدیهی است که ممکنه یک writer ای از یک متد backup گیری خاص پشتیبانی بکنه یا نکنه، که طبعا اگه نکنه نمی توانید اون متد backup رو با اون writer بکار ببرید. اما بررسی همه writer ها هم برای شما کاربردی نداره. دلیلش اینه که هر writer ای فقط روی داده هایی نظارت داره که برای اون منظور طراحی شده. فرضا وقتی دارید از داده های فایل های درایوی backup میگیرید ارتباطی با writer ای که با registry یا sql server تعامل داره نداره چون اونها کاری با تغییرات فایل ها ندارند و درگیر backup شما نمی شوند.
کد:
            DataGridView grid = new DataGridView();
            grid.Columns.Add("name", "Writer Name");
            grid.Columns.Add("support", "Incremental and Differential Support");
            grid.Columns["name"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            grid.Columns["support"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            grid.Dock = DockStyle.Fill;
            grid.RowHeadersVisible = false;
            grid.ReadOnly = true;
            grid.Parent = this;
            IVssImplementation vssImplementation = VssUtils.LoadImplementation();
            using (IVssBackupComponents vssBackup = vssImplementation.CreateVssBackupComponents())
            {
                vssBackup.InitializeForBackup(null);
                vssBackup.GatherWriterMetadata();
                foreach (var writer in vssBackup.WriterMetadata)
                {
                    var support = "";
                    if ((writer.BackupSchema & VssBackupSchema.ExclusiveIncrementalDifferential) == VssBackupSchema.ExclusiveIncrementalDifferential)
                    {
                        support += " Exclusive";
                    }
                    if ((writer.BackupSchema & VssBackupSchema.Differential) == VssBackupSchema.Differential)
                    {
                        support += " Differential";
                    }
                    if ((writer.BackupSchema & VssBackupSchema.Incremental) == VssBackupSchema.Incremental)
                    {
                        support += " Incremental";
                    }
                    grid.Rows.Add(writer.WriterName, support.Trim());
                }
            }

از طرف دیگه امکان backup گیری فقط از یکسری فایل ها رو هم احتمالا ندارید، چون backup اولیه تون کل داده های یک volume رو شامل شده و انتخابی نبوده. اونم به خاطر اینه که قابلیت backup گیری صرفا از بعضی از فایل ها ظاهرا مخصوص ویندوز سرور ها است. به همین جهت قاعدتا در مورد سوم کار زیادی برای انجام ندارید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنونم استاد علی
ممنون که کد دادین . الان این کد برای مرحله ی اولش بود . درسته؟
بیشتر ، منظورم این بود که برای گرفتن بکاپ افزایشی و تفاوتی ، بصورت کلی و در دید کلی چی کار باید کرد؟
فقط کافیه اون ۴ مرحله را برم؟ قضیه ی متد SetPreviousBackupStamp باید انجام بشه و اگه آره ، در کجای اون مراحل باید انجام بشه؟ برای شماره ی ۳ اش که گفته بودم ، راهنمایی کلی میکنین که باید چی کار کنم؟
 

the_king

مدیرکل انجمن
خیلی ممنونم استاد علی
ممنون که کد دادین . الان این کد برای مرحله ی اولش بود . درسته؟
بله، مربوط به مرحله اول بود ولی مرحله اول برای کد نویسی در برنامه نهایی تون نیست ها، برای اینه که به عنوان برنامه نویس بدونید چطور بررسی کنید که متد backup ای که میخواهید پشتیبانی میشه یا نه.
مرحله اول مقدمات ئه. نمیگه کدش رو در برنامه تون بنویسید تا هر بار چک بشه. فقط میگه برای اینکه بتوانید این backup گیری رو انجام بدید در ابتدا چه مقدمات و امکاناتی باید موجود باشه.
یعنی میگه اگه writer تون پشتیبانی اش نمی کنه اصلا عملی نیست و روش چک کردن پشتیبانیش اینه. همین. نمیگه حالا کدی بنویسید که روی سیستم کاربر بررسی اش کنه. کدی که نوشتم صرفا مشاهده نتایجی بود که اگر مرحله اول رو انجام میدادید بهش می رسیدید. اون بررسی برای نرم افزارتون کاربردی نیست چون منعطف ترین سیستم backup گیری هم نمیتونه با همه writer ها کاری داشته باشه، هر نرم افزاری اگه از writer مشخصی استفاده کنه از قبل میدونه که پشتیبانی اش در چه حدیه. کد برای بررسی نمیخواد. الان اگه اون نتایج رو یکبار در اجرا ببینید برای آینده کافیه، لازم نیست از کدش استفاده کنید.
دیگه دلیلی نداره که روی سیستم کاربر همچین بررسی ای انجام بشه. مثل اینکه من میدونم اسم فایل نمیتونه شامل کاراکتر های / و \ باشه، یکبار هم در کل عمرم بررسی اش کنم کافیه. دیگه لازم نیست که در اول برنامه ام چک کنم ببینم قبولش می کنه یا نه.

من از گزارش writer های روی سیستم ام نتیجه می گیرم که هیچکدوم از writer های نصب شده روی ویندوز 7 ام همچین توانایی رو نداره که backup به شیوه Incremental بگیره. فقط هم SqlServerWriter میتونه به شیوه Differential کار کنه که اونم برای پایگاه داده است، مناسب فایل های روی Volume نیست. از طرف دیگه دو تا برنامه برای مشاهده snapshot ها بررسی کردم که هیچکدوم نمی توانند مشخص کنند که snapshot به فلان شیوه backup گرفته شده. این وضعیت مطلوب نیست، چون اگر شما backup ای بگیرید که بدون خطا انجام بشه و نتوانید بفهمید واقعا به چه شیوه ای گرفته شده فایده نداره. جایی هم مطلبی نخوندم که نوشته شده باشه کسی همچین کاری انجام داده یا نداده.

بیشتر ، منظورم این بود که برای گرفتن بکاپ افزایشی و تفاوتی ، بصورت کلی و در دید کلی چی کار باید کرد؟
فقط کافیه اون ۴ مرحله را برم؟ قضیه ی متد SetPreviousBackupStamp باید انجام بشه و اگه آره ، در کجای اون مراحل باید انجام بشه؟ برای شماره ی ۳ اش که گفته بودم ، راهنمایی کلی میکنین که باید چی کار کنم؟

متاسفانه نه جزئیات رو میدونم و نه امکان تست عملی شو ندارم و نه نتیجه میتونم بگیرم که روش درستی هست یا نه.
نه. در پیاده سازی که قطعا چهار مرحله ای کار نمی کنید، برنامه شما requester ئه. شما writer که نمی نویسید. عنوان مطلبی که خوندید نقش writer ئه در backup گیری، نه صحبت از مرحله است و نه اگه مرحله باشه مراحلی است که requster در backup گیری انجام میده، شما requester می نویسید. اون به قول شما مرحله اول هم مقدمات و پایه است که دیگه در کدتون نخواهد بود. alphavss که کلا در راهنماش نوشته که خودش اجازه طراحی writer به شما رو نمیده که البته نیاز شما هم نیست، شما writer اختصاصی لازم ندارید.
مرحله ابتدایی رو قبلا گفتم، شما دارید backup ای میگیرید که مبنا اش یک backup قبلیه، اول باید snapshot اون backup قبلی رو پیدا کنید تا مشخص بشه مبنا چیه و time stamp اش هم معلوم باشه. نمیتونید بگید backup بگیره بدون اینکه مبنا شو مشخص کنید. اول باید snapshot مبنا رو پیدا کنید :
گفتگو هایی در باب سی شارپ
بعد time stamp اون snapshot رو به عنوان Previous Stamp در روال backup گیری تون مشخص می کنید، لابد بعد از اینکه متد backup گیری رو با SetBackupState مشخص کردید.
این چیزی که میگم حرفی است که در مورد بکار گیری SetPreviousBackupStamp نوشته شده :
IVssBackupComponents.SetPreviousBackupStamp Method

جستجو با QuerySnapshots و پیدا کردن snapshot مبنا و گرفتن مقدار مشخصه CreationTimestamp اش کار راحت و سر راستیه اما برای استفاده از SetPreviousBackupStamp چند تا مشکل می بینم. اول اینکه در مشخصات snapshot ها اشاره ای به writeid نشده و حتی روی سیستم در لیست writer ها موردی پیدا نمی کنم که هم Incremental و Differential رو پشتیبانی کنه و از اون مهمتر با نیازتون سازگار باشه. از طرف دیگه باید بتوانیم تشخیص بدهیم که فلان snapshot به شیوه فلان گرفته شده.
مشخصه ای نمیبینم که اعلام کنه که فلان Shadow به فلان شیوه گرفته شده. یعنی اگه شما id یک snapshot رو بدهید به GetSnapshotProperties در همون حدی اطلاعات بهتون میده که vssadmin list shadows و VssBackupType جزئی از اینها نیست. اگه مشخصه vssBackup.GetSnapshotProperties(snapshotId).SnapshotAttributes رو ببینید اصلا فیلدی برای Incremental نداره، Differential اش هم مربوط به Copy on Write ئه، منظور اون شیوه Differential در backup گیری نیست، حتی اگه Backup از نوع full هم بگیرید SnapshotAttributes اش Differential نشون میده.
و componentName هم نامشخصه، شما در backup گیری قبلی تون هم بدون component اینکار رو انجام میدید که اونم تاکید شده نباید null باشه.
و امکان تست و بررسی کدی رو ندارم که بگم فلانطور بنویسید کار کنه.

مشکل اول اینه که حتی توسط یک برنامه مشخص چطور میشه فهمید یک shadow با چه متدی گرفته شده، Full یا Differential یا Incremental. همچین چیزی نمی بینم.
 

جدیدترین ارسال ها

بالا