سلام
من میخوام یه متغیری از struct یا یه object رو تو یه فایل ذخیره کنم .می خواستم ببینم از چه دستوری باید استفاده کنم ؟
سلام
من میخوام یه متغیری از struct یا یه object رو تو یه فایل ذخیره کنم .می خواستم ببینم از چه دستوری باید استفاده کنم ؟
باید اونو serialize کنی و در فایل ذخیره کنی، باید NameSpaceهای زیر رو به پروژه ات اضافه کنی :
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
این یه نمونه کد هست برای ذخیره ی آبجکت lstStoreItems در فایلی به نام StoreItems.sti :
string strFileName = "StoreItems.sti";
FileStream fStream = new FileStream(strFileName,FileMode.Create);
BinaryFormatter binFormat = new BinaryFormatter();
try
{
binFormat.Serialize(fStream,this.lstStoreItems);
}
catch(ArgumentNullException)
{
MessageBox.Show("دسترسی به ذخایر امکان پذیر نیست","خطا ");
}
catch(SerializationException)
{
MessageBox.Show("امکان ذخیره اطلاعات وجود ندارد","خطا ");
}
finally
{
fStream.Close();
}
و اینم کدی هست که میتونی آبجکت ذخیره شده در فایل رو مجددا بازیابی کنی (این قسمت درست برعکس مرحله ی قبله، یعنی تو مرحله ی قبل serialize کردی، اینجا باید deserialize کنی) :
string strFileName = "StoreItems.sti";
FileStream fstream = null;
if(File.Exists(strFileName))
{
try
{
fstream = new FileStream(strFileName,FileMode.Open);
BinaryFormatter binFormat = new BinaryFormatter();
lstStoreItems = (ArrayList)binFormat.Deserialize(fstream);
}
catch(ArgumentNullException)
{
MessageBox.Show("دسترسی به ذخایر امکان پذیر نیست","خطا ");
}
catch(SerializationException)
{
MessageBox.Show("امکان باز یابی اطلاعات وجود ندارد","خطا ");
}
finally
{
fstream.Close();
}
}
else
return;
موفق باشید.
خیلی خیلی ممنون دوست عزیز
نمیدونم درست متوجه شدم یا نه ولی آیا این serialize کردن اطلاعات رو به صورت باینری در میاره و بعد تو فایل ذخیره میکنه یا نه؟
یه سوال دیگه هم اینکه lstStoreItems یه شیء از کلاس ArrayList هست؟
آیا این serialize کردن اطلاعات رو به صورت باینری در میاره و بعد تو فایل ذخیره میکنه یا نه؟
بله عزیزم، به صورت باینری در فایل ذخیره میشه.
یه شیء از کلاس ArrayList هست؟
نه عزیزم، این کلاسی هست که خودم نوشتم، راستی خوب شد یادم انداختی، قبل از تعریف کلاست، باید خصیصه ی [Serializable] رو در ابتدای تعریف کلاست ذکر کنی، مثل این کد که من در ابتدای تعریف کلاس CStoreItem خودم ذکر کردم :
namespace StoreItem
{
/// <summary>
/// Summary description for Class1.
/// </summary>
[Serializable]
public class CStoreItem
{
private string nm;
private string cd;
private int nmi;
//some code ...
موفق باشید.
بازم خیلی ممنون از لطفتون
پس چرا موقع باز گردانی اطلاعات از فایل اونو به شیء کلاس ArrayList تبدیل کردین؟نه عزیزم، این کلاسی هست که خودم نوشتم،
lstStoreItems = (ArrayList)binFormat.Deserialize(fstream);
مگه نباید به شی ایی از همون کلاسی که بوده تبدیل بشه؟
[Serializable] باعث میشه که کلاس شما قابلیت ذخیره شدن در فایل به صورت جریانی از داده ها رو که به صورت سریالی و پشت سرهم در اومدن رو داشته باشه، بدیهی است که زمان نمایش و بازیابی، باید اون رو به صورت جریانی از داده ها (آرایه نمونه ی خوبی میتونه باشه) بارگذاری کنیم، میتونی به جای ArrayList، آرایه ای از بایتها رو در نظر بگیری (byte[])، ولی بهترین گزینه arrayList هست چون هر داده ای رو میتونی در اون نگهداری کنی، در ضمن فکر میکنم بتونی تو همون ArrayList نگهداری کنی و مشکلی پیش نیاد.
منظورتون اینه که مثلا اگه چند تا object توی فایل به صورت پشت سر هم ذخره شدن میشه اون ها به شی کلاس Arraylist تبدیل کرد؟ یعنی به فرض بشه به هر شی که تو فایل بوده به صورتی اندیسی در شی کلاس Arraylist دست پیدا کرد؟
من یه کلاسی به اسم person نوشتم و بعد برای باز گردوندن اطلاعات از فایل اونو این جوری نوشتم و مشکل پیدا کرد . منطقی هم هست چون نمیشه یه شیئ از کلاس Arraylist رو ریخت تو شیئ کلاس person
person objperson=(ArrayList)binformat.Deserialize(objfile);
اون کدتون رو به شکل زیر تغییر بدید:
ArrayList list=(ArrayList)bin.Deserialize(objfile);
یا به شکل زیر:
person list=(person)bin.Deserialize(objfile);
با تشکر
ولی آیا این درسته که وقتی شیئ کلاس person رو ریختیم تو فایل بعد موقع باز خوانی اون رو به Arraylist تبدیل کنیم ؟ اگه درسته حالا که به شی کلاس ArrayList تبدیل شده چه جوری باید به متغیر هایی که تو object تعریف کرده بودم دست پیدا کنم؟
یه سوال دیگه هم دارم:
برای ذخیره چند تا object از یه کلاس باید چیکار کرد البته خودم فکر کنم باید از seek استفاده کنم تا جای رو که تو فایل یه شی باید ذخیره بشه عوض کنم درسته؟ اگه میشه در مورد این seek , منظورم پارامتر هایی که میگیره هست یه توضیحی بدیدن
اصولا شما هر چیزی رو میتونید در ArrayList ذخیره کنید.آیا این درسته که وقتی شیئ کلاس person رو ریختیم تو فایل بعد موقع باز خوانی اون رو به Arraylist تبدیل کنیم ؟
اینطوری میتونی به کلاس مورد نظرت برگردونی، از طریق حلقه :حالا که به شی کلاس ArrayList تبدیل شده چه جوری باید به متغیر هایی که تو object تعریف کرده بودم دست پیدا کنم؟
ArrayList lst = new ArrayList();
CStoreItem Item = new CStoreItem();
public int Locates(string ItemName)
{
int j=0;
int k=0;
for(int i=0;i<lst.Count;i++)
{
Item = (StoreItem.CStoreItem)lst[i];
if(Item.ItemName == ItemName)
{
j=Item.NumberInput;
k+=j;
}
}
return k;
}
با تشکر مجدد
یعنی اگه مثلا 10 شی از کلاسی رو تو فایل ذخیره کرده باشیم با نوشتن این خط
lstStoreItems = (ArrayList)binFormat.Deserialize(fstream);
تمام شی ها داخل شی کلاس ArrayList قرار میگیرن یا باید تک تک اونا را قرار داد؟
در مورد سوال دومی هم که پرسیده بودم میشه بفرمایید که برای ریختن چندتا شی تو فایل باید چیکار منم؟ آیا با نوشتن همون دستوراتی که در بالا گفته بودین میشه چندتا شی رو به صورت پشت سر هم تو فایل ریخت و مجددا باز خوانی کرد یا باید کار دیگه ای بکنم؟
با این کار کل فایلت که شامل هرتعداد آبجکت هست در arrayList قرار میگیره.تمام شی ها داخل شی کلاس ArrayList قرار میگیرن یا باید تک تک اونا را قرار داد؟
منظورتو درست متوجه نشدم، خب میتونی مثل خود من یه ابجت از ArrayList بسازی و با متد Add اون آبجکت های مورد نظرت رو بهش اضافه کنی و بعد اون رو serialize کنی و در فایل ذخیره کنی.برای ریختن چندتا شی تو فایل باید چیکار منم؟
درسته منطقی هم همینه که شما میگین هست. ولی به طور مثال این کد رو ببینیدمنظورتو درست متوجه نشدم، خب میتونی مثل خود من یه ابجت از ArrayList بسازی و با متد Add اون آبجکت های مورد نظرت رو بهش اضافه کنی و بعد اون رو serialize کنی و در فایل ذخیره کنی.
الان می خوام این کد 10 تا عدد رو بریزه تو فایل. ولی به جای اعداد فرض کنید 10 شی داریم
این برای ذخیره کردن
privatevoid button1_Click(object sender, EventArgs e)
{
FileStream objfile = newFileStream("c:\\intiger.dat", FileMode.Create);
BinaryFormatter binformat = newBinaryFormatter();
for (int i = 0; i < 10; i++)
{
objfile.Seek(i * sizeof(int), SeekOrigin.Begin);
binformat.Serialize(objfile, i);
}
objfile.Close();
}
و اینم برای باز خوانی از فایل
privatevoid button2_Click(object sender, EventArgs e)
{
int a;
FileStream objfile = newFileStream("c:\\intiger.dat", FileMode.Open);
BinaryFormatter binformat = newBinaryFormatter();
for (int i = 0; i < 10; i++)
{
objfile.Seek( i*sizeof(int), SeekOrigin.Begin);
a=(int)binformat.Deserialize(objfile);
MessageBox.Show(a.ToString());
}
}
البته کد دوم مشکل داره که نفهمیدم درست مشکلش کجاست اگه لطف کنید ببینید مشکلش چیه ممنون میشم .
البته نمیدونم serialize کردن برای شی هاست یا در مورد اعداد هم میشه استفاده کرد .
نوشته شده توسط hdv212جناب hdv212 فکر کنم سوء تفاهمی پیش اومده :) با این جوابها و سوالها، ایشون فکر میکنند که شما یک شیئ از نوع person رو Serialize کردید و موقع خواندن آن از فایل، آنرا بصورت یک شیئ از نوع ArrayList میخونید :)نوشته شده توسط hdv212
خیر. همچنین چیزی نمیشه انجام داد.نوشته شده توسط emad_67
اصلا نمیشه! باید تک تک اونها رو با متد Deserialize بگیرید.نوشته شده توسط emad_67
به مثال زیر توجه کنید، در مثال زیر سه شیئ از نوع person رو Serialize میکنیم:نوشته شده توسط emad_67
formatter.Serialize(fstream, obj1);
formatter.Serialize(fstream, obj2);
formatter.Serialize(fstream, obj3);
و در کد زیر، اون اشیاء رو از فایل، دریافت میکنید:
obj1 = (person)formatter.Deserialize(fstream);
obj2 = (person)formatter.Deserialize(fstream);
obj3 = (person)formatter.Deserialize(fstream);
برای اعداد هم میشه.البته نمیدونم serialize کردن برای شی هاست یا در مورد اعداد هم میشه استفاده کرد .
منظورتون رو از این خط کد نفهمیدم، میخواید چیکار کنید؟
objfile.Seek( i*sizeof(int), SeekOrigin.Begin);
نمیدونم درست فهمیدم یا نه ولی فکز کنم باید این seek جای جریان رو تغییر بده( یعنی اون بایتی که متغییر باید از اون جا write بشه رو تغییر میده) توی این خط
objfile.Seek( i*sizeof(int), SeekOrigin.Begin);
مثلا وقتی i=0 باشه مقدار داخل seek 0 میشه و باید عدد در ابتدای فایل write بشه و حالا وقتی که i=1 میشه در واقع مقدار داخل seek میشه 4 ( 4*1) و باید عدد روی 4 امین بایت فایل نوشته بشه درسته؟ و به همین ترتیب تا آخر یعنی اعداد 1 تا 10 به ترتیب توی فایل ذخیره میشن
در مورد کدی هم که داده بودین
من تو کلاس person یه متغیر رشته ای به عنوان name تعریف کردم و سه تا شی ساختم البته با name های مختلف ولی وقتی این کد:
obj1 = (person)formatter.Deserialize(fstream);
obj2 = (person)formatter.Deserialize(fstream);
obj3 = (person)formatter.Deserialize(fstream);
رو نوشتم فقط 3 بار name اولین شی ایی رو که ذخیره کرده بودم چاپ میکنه یعنی فکر میکنم که هر بار از ابتدای فایل اطلاعات رو می خونه
privatevoid button1_Click(object sender, EventArgs e)
{
FileStream objfile = newFileStream("c:\\intiger.dat", FileMode.Create);
BinaryFormatter binformat = newBinaryFormatter();
for (int i = 0; i < 10; i++)
{
objfile.Seek(i * sizeof(int), SeekOrigin.Begin);
binformat.Serialize(objfile, i);
}
objfile.Close();
}
عزیزم، Serialize رو چرا توی حلقه گذاشتی ؟
با objfile.Seek چکار داری ؟
به جای objfile یه آبجکت از arraylist بساز، و در حلقه، فقط متد Add آبجت arrayList رو فراخوانی کن و در خط اخر و خارج از حلقه، متد Serialize رو فراخوانی کن و آبجکت ArrayList رو بهش پاس کن، اینطوری :
privatevoid button1_Click(object sender, EventArgs e)
{
FileStream objfile = newFileStream("c:\\intiger.dat", FileMode.Create);
BinaryFormatter binformat = newBinaryFormatter();
ArrayList lst = new ArrayList();
for (int i = 0; i < 10; i++)
{
lst.Add(i * sizeof(int));
}
binformat.Serialize(objfile, lst);
objfile.Close();
}
برای بازیابی هم، اینطوری :
privatevoid button2_Click(object sender, EventArgs e)
{
ArrayList lst = new ArrayList();
FileStream objfile = newFileStream("c:\\intiger.dat", FileMode.Open);
BinaryFormatter binformat = newBinaryFormatter();
lst = (ArrayList)binformat.Deserialize(objfile);
}
واسه چی از حلقه استفاده کردی ؟ تمام این کارها با ArrayList انجام شد، در صورت نیاز باید به صورت دستی اونو به آبجکت مورد نظرت تبدیل کنی(اینجا بایستی از حلقه استفاده کنی)
درسته روش منطقی ، همین روشی هست که شما میگید ولی من می خواستم جوری برنامه رو بنویسم که که شی ایی از نوع Arraylist رو که حاوی همه اشیا یا اعداد هست رو ذخیره نکنم . یعنی تک تک ، اعداد رو بریزم تو فایل ( فقط جهت یاد گیری ولی روش اصلی همین روشی هست که شما میگید)
باز هم خیلی ممنون
هر بار از ادامه میخونه...رو نوشتم فقط 3 بار name اولین شی ایی رو که ذخیره کرده بودم چاپ میکنه یعنی فکر میکنم که هر بار از ابتدای فایل اطلاعات رو می خونه
نیازی به تکه کد زیر نیست:
objfile.Seek( i*sizeof(int), SeekOrigin.Begin);
چون خودش، ادامه داده ها رو در ادامه فایل میریزه.