PDA

View Full Version : ذخیره و بازیابی فایل در دیتابیس و سایر مسائل مربوط به آن



piroozman
دوشنبه 30 شهریور 1388, 23:41 عصر
در برنامه ای قصد بر این داریم فایلی را از داخل کامپیوتر انتخاب کرده و آنرا در یک دیتابیس ذخیره کنیم. برای این کار از کدهای زیر استفاده کرده ام:



public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private string strFileName;
private byte[] fileType;


private void t1BindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.t1BindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.testDataSe t);


}


private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'testDataSet.t1' table. You can move, or remove it, as needed.
this.t1TableAdapter.Fill(this.testDataSet.t1);


}


private void selectButton_Click(object sender, EventArgs e)
{
try
{
if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
{
strFileName = openFileDialog1.FileName;
fileType = System.IO.File.ReadAllBytes(strFileName);
this.t1DataGridView[1, this.t1DataGridView.CurrentCell.RowIndex].Value = fileType;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error");
}
}
}

برای ذخیره کردن و حذف رکورد ها در دیتابیس از TableAdapter استفاده کرده ام. اگر پروژه ای که به این تاپیک ضمیمه شده است را باز کنید، خواهید دید که ستونی از دیتاگریدویو را که مقدار فایل ها در آن قرار می گیرد به صورت کلید است. حال سئوالم اینجاست:
1. چگونه می توانم نام فایل را از انتهای مسیری که فایل انتخاب می شود جدا کنم و به صورت یک متغیر آنرا بدست بیاورم. چون قصد دارم نام فایل را در دیتابیس ذخیره کنم.
2. پس از ذخیره نام فایل چگونه می توانم نام آنرا بر روی کلیدهای هر رکوردی که نشانگر فایل است نمایش دهم.
3. همانطور که در کدها مشاهده می کنید این امکان وجود دارد که هر فایلی را در دیتابیس ذخیره کنید. از فایلهای آفیس، تصویری و . . . اما چگونه فایل را اجرا کنم. قصد دارم فایل اگر مثلا یک فایل اتوکد است برنامه آنرا با اتوکد باز کند و اگر وورد است یا اکسل آنرا با نرم افزار مربوطه باز کند.
4. قصد دارم فایل را در یک مسیر موقت باز کنم. مثلا در temp ویندوز. هدفم این است که کاربر بتواند روی فایل تغییرات را ایجاد کند و سپس آنرا در دیتابیس ذخیره کند. بنده فکر می کنم باید یک نام تصادفی به این فایل که قرار است در temp ویرایش شود، بدهم. چگونه این کار را می توانم انجام دهم طوری که نام مشابه ای در همان temp با نامی که من به فایل جدید می دهم وجود نداشته باشد.
5. چگونه می توان فایلی را (نه کل رکورد) را از رکورد خاصی حذف کنم.
اگر دوستان کمک کنند این تاپیک را به انتها برسونیم مطالب را جمع و جور کرده و در همین تاپیک به صورت مشخص و معینی اضافه میکنم تا دوستان دیگر نیز بتوانند از آن استفاده کنند. ضمنا اگر کسی ایده جدیدی دارد لطف می کنه در همین تاپیک اعلام کنه. از کلیه دوستانی که به بنده جواب می دهند قبلا تشکر می کنم
نکته آخر این که T-SQL ایجاد دیتابیس و جدول مربوطه و نیز پروژه ضمیمه می باشد.

mn_zandy63
سه شنبه 31 شهریور 1388, 07:32 صبح
سلام دوست عزیز
چند دقیقه فرصت دارم، سوالاتت رو هرکدوم که فرصت بشه و الان بدونم جوابش رو بهت میگم، بقیه رو بعدا خودم، یا دیگر دوستان پاسخ خواهند داد.
در مورد سوال اولت، اگه درست سوالت رو متوجه شده باشم، System.IO.Path رو اگه یک نیگاه بندازی خودت متوجه خوهی شد، تابع System.IO.Path.GetFileName و دیگر توابع موجود کارت رو راه میندازن.
سوال چهارمت هم، همین کلاس، تابعی به نام GetTempFileName داره.
منظورت رو از سوال 2 و 5 متوجه نشدم.
موفق باشی.

piroozman
سه شنبه 31 شهریور 1388, 10:45 صبح
منظورت رو از سوال 2 و 5 متوجه نشدم.
موفق باشی.
ضمن تشکر.
منظورم از سئوال دوم:
نوع ستونی از دیتاگریدویو که به ستون فایل DataTable بایند شده است را از نوع Button گذاشته ام.ستون دارای خصیصه ای به نام Text است و می خوام مقدار Text ی که روی کلید مشاهده می شود نام فایل باشد. هر چی بررسی کردم نتونستم این خصیصه را به ستونی از دیتاتیبل بایند کنم.
منظورم از سئوال پنجم:
فرض کنیم در Table سه رکورد داریم و این رکورد ها هر کدام دارای یک فایل می باشند. حالا می خواهم مثلا رکورد دوم فیلدی که در ان فایل ذخیره شده است را از ان رکورد حذف کنم. نه خود رکورد. به نوعی می خواهم یک رکورد یافته و مقدار فیلدی که از نوع varbinary است رو حذف کنم.
امیدوارم درست تونسته باشم سئوالم رو مطرح کنم.
اما هنوز مشکل اصلی بنده یعنی همان اجرای فایل باقی مانده و نتونسته ام اونرو حل کنم. لطف می کنند کسانی که بنده را کمک کنند.
باز هم تشکر

mn_zandy63
سه شنبه 31 شهریور 1388, 20:54 عصر
سلام دوست عزیز
در مورد اجرای فایل، خب شما اگه از داخل دیتابیس توی یک فایل temp بریزی فایلت رو، فکر میکنم با تابع Start از کلاس Process بتونی به راحتی هر فایلی رو باز کنی.
const string fileAddress = @"D:\picture.jpg";
System.Diagnostics.Process.Start(fileAddress);

اگه آدرس یک فایل غیر اجرایی رو بدی به این تابع، ویندوز به صورت خودکار با برنامه ای که برای Ext اول فایل تعریف شده باز خواهد کرد، بنابراین نگران نحوه باز کردن فایل نباشید.
در مورد عنوان روی دکمه، شما اگه مشخصهء (DataBindings) رو نیگاه کنی، (دومین Property از بالا) تحت این مشخصه، Text رو داری، که میتونی عنوان دکمه رو Bind کنی باهاش، بقیه مشخصات Button رو اگه خواستی بایند کنی باید روی Advanced کلیک کنی.
http://barnamenevis.org/forum/attachment.php?attachmentid=37337&stc=1&d=1253641549
در مورد پاک کردن فایل از رکورد، خب چرا Null نمیکنی اون فیلد رو؟

hdv212
چهارشنبه 01 مهر 1388, 01:48 صبح
1. چگونه می توانم نام فایل را از انتهای مسیری که فایل انتخاب می شود جدا کنم و به صورت یک متغیر آنرا بدست بیاورم. چون قصد دارم نام فایل را در دیتابیس ذخیره کنم.
از کلاس System.IO.FileInfo استفاده کنید، این کلاس دارای Propertyای هست فکر کنم به نام FileName که نام فایل رو برمیگردونه.


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


3. همانطور که در کدها مشاهده می کنید این امکان وجود دارد که هر فایلی را در دیتابیس ذخیره کنید. از فایلهای آفیس، تصویری و . . . اما چگونه فایل را اجرا کنم. قصد دارم فایل اگر مثلا یک فایل اتوکد است برنامه آنرا با اتوکد باز کند و اگر وورد است یا اکسل آنرا با نرم افزار مربوطه باز کند.
شما میتونید فایل مورد نظر رو با تابع System.Diagnostics.Process.Start اجرا کنید، این کار مثل این میمونه که انگار با ماوس روی فایل مورد نظر دوبل کلیک کردید، اگر برنامه مورد نظر نصب شده باشه، ویندوز فایل شما رو با اون باز میکنه.


4. قصد دارم فایل را در یک مسیر موقت باز کنم. مثلا در temp ویندوز. هدفم این است که کاربر بتواند روی فایل تغییرات را ایجاد کند و سپس آنرا در دیتابیس ذخیره کند. بنده فکر می کنم باید یک نام تصادفی به این فایل که قرار است در temp ویرایش شود، بدهم. چگونه این کار را می توانم انجام دهم طوری که نام مشابه ای در همان temp با نامی که من به فایل جدید می دهم وجود نداشته باشد.
پیشنهاد میکنم، فایل مورد نظرتون رو با نام کلیداصلی+تاریخ جاری با دقت صدم ثانیه ذخیره کنید و پس از ذخیره مجدد در دیتابیس اونو پاک کنید، میتونید اونو مخفی هم بکنید تا حداقل به صورت مخفی باشه.


5. چگونه می توان فایلی را (نه کل رکورد) را از رکورد خاصی حذف کنم.
این کار با یک دستور ساده Update و null کردن فیلد مورد نظر انجام میشه!

موفق باشید

piroozman
چهارشنبه 01 مهر 1388, 20:23 عصر
پیشنهاد میکنم، فایل مورد نظرتون رو با نام کلیداصلی+تاریخ جاری با دقت صدم ثانیه ذخیره کنید و پس از ذخیره مجدد در دیتابیس اونو پاک کنید، میتونید اونو مخفی هم بکنید تا حداقل به صورت مخفی باشه.

ضمن تشکر. میشه لطفا بیشتر توضیح بدهید. بنده فایل را از دیتابیس در یک MemoryStream می ریزم. حالا چطوری می تونم این Stream را همراه با نام در یک دایرکتوری ذخیره کنم.

piroozman
چهارشنبه 01 مهر 1388, 20:28 عصر
در مورد اجرای فایل، خب شما اگه از داخل دیتابیس توی یک فایل temp بریزی فایلت رو، فکر میکنم با تابع Start از کلاس Process بتونی به راحتی هر فایلی رو باز کنی.
const string fileAddress = @"D:\picture.jpg";
System.Diagnostics.Process.Start(fileAddress);


ضمن تشکر. دقیقا منظور من اینه که چطوری یک فیلدی از بیت ها را ابتدا نام بدم و سپس در مسیری مثلا همون مسیری که شما نوشته اید ذخیره کنم. منظور اجرای خود فایل با دستوری که شما نوشتید نبود.

hdv212
پنج شنبه 02 مهر 1388, 01:01 صبح
ضمن تشکر. میشه لطفا بیشتر توضیح بدهید. بنده فایل را از دیتابیس در یک MemoryStream می ریزم. حالا چطوری می تونم این Stream را همراه با نام در یک دایرکتوری ذخیره کنم.

از کلاسهای System.IO.StreamWriter (http://msdn.microsoft.com/en-us/library/system.io.streamwriter.aspx) یا System.IO.BinaryWriter (http://msdn.microsoft.com/en-us/library/system.io.binarywriter.aspx) میتونید برای این کار استفاده کنید.

mn_zandy63
پنج شنبه 02 مهر 1388, 01:49 صبح
سلام دوست عزیز
شما گفتی کل فایلت رو خوندی از دیتابیس ریختی داخل یک memorystream، فرض کنیم اسمش ms باشه.
string fileName = System.IO.Path.GetTempFileName();

System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Create);
ms.WriteTo(fs);
fs.Close();


با توجه به اینکه گفته بودید میخواین فایل رو اجرا کنین بعد از اینکه از دیتابیس خوندینش،
پس شما پسوند فایل رو دارید
من یک نمونه کد برای اینکار براتون مینویسم میتونید روش کار کنید اون چیزی که میخواید رو ازش در بیارید.
const string ext = "PNG";

string tempFolder = System.IO.Path.GetTempPath();
string fileName = string.Format(@"{0}{1}.{2}", tempFolder, Guid.NewGuid(), ext);

System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Create);
ms.WriteTo(fs);
fs.Close();

System.Diagnostics.Process.Start(fileName);


موفق باشید.