كيفية قراءة وكتابة ملف من عمود النقطة باستخدام chunking في ADO.NET و Visual C#.NET

للحصول على إصدار Microsoft Visual Basic.NET من هذه المقالة، راجع
317034 .
للحصول على إصدار Microsoft Visual c + +.NET من هذه المقالة، راجع
317044 .

ملخص

توضح هذه المقالة خطوة بخطوة كيفية استخدام بيانات Microsoft SQL Server READTEXT و UPDATETEXT لقراءة وكتابه البيانات من الأعمدة BLOB (LongVarBinary) في جدول قاعدة بيانات.

بسبب قيود الشبكة، قد يلزم استرداد ملف BLOB كبير في قطع أصغر وثم قطعة من قطع معا بدلاً من استرداد الملف النقطة في وقت واحد. ومع ذلك، موفري البيانات ADO.NET ليس الأساليب المتاحة لكائن الوصول إلى البيانات (DAO) وكائنات مجموعة السجلات من كائنات بيانات ActiveX "(ADO) GetChunk و AppendChunk . توضح هذه المقالة الطرق المختلفة لاسترداد البيانات في قطع أصغر.

ملاحظات:
  • تحتوي هذه المقالة على أمثلة لكل موفر البيانات SqlClient و OLE DB موفر بيانات.NET. الاختلافات فقط، وبصرف النظر عن أسماء الفئات، هي سلاسل اتصال وتعريف معلمات SQL. التقنية الأساسية لاسترداد البيانات READTEXT و UPDATETEXT هو نفسه.
  • لا يوجد سجل اختبار في جدول الفئات من قاعدة بيانات نموذج Northwind. يجب استخدام "مستكشف الملقم" أو أداة أخرى لإضافة سجل مع اسم الفئة تعيين اختبار. بعد استخدام نماذج التالية، قد تحتاج إلى إزالة هذا السجل من قاعدة البيانات. لإزالة السجل، اكتب الأمر التالي في محلل استعلام SQL، ومن ثم اضغط F5:
    use Northwinddelete from Categories where CategoryName = 'Test'

العودة إلى أعلى

متطلبات

العناصر التالية تصف الأجهزة الموصى بها والبرامج، والبنية الأساسية للشبكة، المهارات والمعارف وحزم الخدمات المطلوبة:
  • متقدمة ملقم Windows 2000 أو نظام التشغيل Microsoft Windows 2000 Professional، Windows 2000 Server أو ملقم Microsoft Windows NT 4.0
  • Microsoft Visual Studio.NET
  • Microsoft SQL Server 7.0 أو ما بعدة
تفترض هذه المقالة أنك معتاد على أساسيات ADO.NET وبناء الجملة.

العودة إلى أعلى

أنشئ مشروع ثم أضف التعليمات البرمجية

  1. افتح SQL Query Analyzer.
  2. اكتب الأمر التالي، ثم اضغط F5 لتغيير قاعدة البيانات الافتراضية إلى Northwind:
    use Northwind
  3. اكتب الأمر التالي، ثم اضغط F5 لإدراج سجل جديد في جدول الفئات من قاعدة بيانات Northwind:
    Insert into categories(categoryname) values ('Test')
    ملاحظة: يجب عليك إضافة هذا السجل إلى جدول "الفئات" إذا كنت تريد استخدام هذا المثال دون تعديل أي من البيانات الموجودة في هذا الجدول فقط.
  4. في Visual Studio.NET, إنشاء مشروع جديد في Visual C# Windows تطبيق.NET.
  5. Athe أعلى ملف Form1.cs إضافة السطرين التاليين من التعليمات البرمجية لإضافة مراجع إلى المشروع الخاص بك من أجل System.Data.SQLClient و System.Data.OleDb:
    using System.Data.SqlClient;using System.Data.OleDb;
  6. إضافة الأزرار الأربعة إلى Form1. تغيير الخاصية Text الأزرار إلى SQLBlob2File، OlDbBlob2File، File2OleDbBlobو File2SqlBlob، على التوالي.
  7. إضافة تعريفات المتغيرات السلسلة التالية ضمن فئة Form1 العامة:
    string destfilepath;string sourcefilepath;

  8. قم بلصق التعليمة البرمجية التالية ضمن الحدث Load النموذج:
    destfilepath = @"c:\mytest.bmp";sourcefilepath = @"c:\windows\coffee bean.bmp";

  9. استدعاء الإجراءات في الحدث Click لكل زر:
    // Click event for the button labeled SqlBlob2File.SqlChunkBlob2File(destfilepath);

    // Click event for the button labeled OLDbBlob2File.
    OlDbChunkBlob2File(destfilepath);

    // Click event for the button labeled File2OleDbBlob.
    ChunkFile2OleDbBlob(sourcefilepath);

    //Click event for the button labeled File2SqlBlob.
    ChunkFile2SqlBlob(sourcefilepath);

  10. قم بلصق المهام الأربع التالية في Form1:
    public void SqlChunkBlob2File(string DestFilePath){
    try
    {
    int PictureCol = 0; // position of Picture column in DataReader
    int BUFFER_LENGTH = 32768; // chunk size
    SqlConnection cn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;");

    // Make sure Photo is non-NULL and return TEXTPTR to it.

    SqlCommand cmdGetPointer = new SqlCommand("SELECT @Pointer=TEXTPTR(Picture), @Length=DataLength(Picture) FROM Categories WHERE CategoryName='Test'", cn);
    SqlParameter PointerOutParam = cmdGetPointer.Parameters.Add("@Pointer", SqlDbType.VarBinary, 100);
    PointerOutParam.Direction = ParameterDirection.Output;
    SqlParameter LengthOutParam = cmdGetPointer.Parameters.Add("@Length", SqlDbType.Int);
    LengthOutParam.Direction = ParameterDirection.Output;
    cn.Open();
    cmdGetPointer.ExecuteNonQuery();
    if(PointerOutParam.Value == null)
    {
    cn.Close();
    // Add code to handle NULL BLOB.
    return;
    }

    // Set up READTEXT command, parameters, and open BinaryReader.

    SqlCommand cmdReadBinary = new SqlCommand("READTEXT Categories.Picture @Pointer @Offset @Size HOLDLOCK", cn);
    SqlParameter PointerParam = cmdReadBinary.Parameters.Add("@Pointer", SqlDbType.Binary, 16);
    SqlParameter OffsetParam = cmdReadBinary.Parameters.Add("@Offset", SqlDbType.Int);
    SqlParameter SizeParam = cmdReadBinary.Parameters.Add("@Size", SqlDbType.Int);
    SqlDataReader dr;
    System.IO.FileStream fs = new System.IO.FileStream(DestFilePath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
    int Offset= 0;
    OffsetParam.Value = Offset;
    Byte []Buffer = new Byte[BUFFER_LENGTH ];


    // Read buffer full of data and write to the file stream.

    do
    {
    PointerParam.Value = PointerOutParam.Value;

    // Calculate buffer size - may be less than BUFFER_LENGTH for last block.

    if( (Offset + BUFFER_LENGTH) >= System.Convert.ToInt32(LengthOutParam.Value))
    SizeParam.Value = System.Convert.ToInt32(LengthOutParam.Value) - Offset;
    else SizeParam.Value = BUFFER_LENGTH;

    dr = cmdReadBinary.ExecuteReader(CommandBehavior.SingleResult);
    dr.Read();
    dr.GetBytes(PictureCol, 0, Buffer, 0, System.Convert.ToInt32(SizeParam.Value));
    dr.Close();
    fs.Write(Buffer, 0, System.Convert.ToInt32(SizeParam.Value));
    Offset += System.Convert.ToInt32(SizeParam.Value);
    OffsetParam.Value = Offset;
    }while(Offset < System.Convert.ToInt32(LengthOutParam.Value));

    fs.Close();
    cn.Close();
    }
    catch(SqlException ex)
    {
    MessageBox.Show (ex.Message);
    }
    }

    public void OleDbChunkBlob2File(string DestFilePath)
    {
    try
    {
    int PictureCol= 0; // Position of picture column in DataReader.
    int BUFFER_LENGTH = 32768;// Chunk size.
    OleDbConnection cn = new OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;");

    // Make sure Photo is non-NULL and return TEXTPTR to it.

    OleDbCommand cmdGetPointer = new OleDbCommand("SELECT ?=TEXTPTR(Picture), ?=DataLength(Picture) FROM Categories WHERE CategoryName='Test'", cn);
    OleDbParameter PointerOutParam = cmdGetPointer.Parameters.Add("@Pointer", OleDbType.VarBinary, 100);
    PointerOutParam.Direction = ParameterDirection.Output;
    OleDbParameter LengthOutParam = cmdGetPointer.Parameters.Add("@Length", OleDbType.Integer);
    LengthOutParam.Direction = ParameterDirection.Output;
    cn.Open();
    cmdGetPointer.ExecuteNonQuery();
    if(PointerOutParam.Value == DBNull.Value )
    {
    cn.Close();
    // Add code to deal with NULL BLOB.
    return;
    }

    // Set up READTEXT command, parameters, and open BinaryReader.

    OleDbCommand cmdReadBinary = new OleDbCommand("READTEXT Categories.Picture ? ? ? HOLDLOCK", cn);
    OleDbParameter PointerParam = cmdReadBinary.Parameters.Add("@Pointer", OleDbType.Binary, 16);
    OleDbParameter OffsetParam = cmdReadBinary.Parameters.Add("@Offset", OleDbType.Integer);
    OleDbParameter SizeParam = cmdReadBinary.Parameters.Add("@Size", OleDbType.Integer);
    OleDbDataReader dr;
    System.IO.FileStream fs = new System.IO.FileStream(DestFilePath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
    int Offset= 0;
    OffsetParam.Value = Offset;
    Byte[] Buffer = new Byte[BUFFER_LENGTH];

    //Read buffer full of data and write to the file stream.

    do
    {
    PointerParam.Value = PointerOutParam.Value;

    // Calculate buffer size - may be less than BUFFER_LENGTH for last block.

    if((Offset + BUFFER_LENGTH) >= System.Convert.ToInt32(LengthOutParam.Value))
    SizeParam.Value = System.Convert.ToInt32(LengthOutParam.Value) - Offset;
    else SizeParam.Value = BUFFER_LENGTH;

    dr = cmdReadBinary.ExecuteReader(CommandBehavior.SingleResult);
    dr.Read();
    dr.GetBytes(PictureCol, 0, Buffer, 0, System.Convert.ToInt32(SizeParam.Value));
    dr.Close();
    fs.Write(Buffer, 0, System.Convert.ToInt32(SizeParam.Value));
    Offset += System.Convert.ToInt32(SizeParam.Value);
    OffsetParam.Value = Offset;
    }while( Offset < System.Convert.ToInt32(LengthOutParam.Value));

    fs.Close();
    cn.Close();
    }
    catch(OleDbException ex)
    {
    MessageBox.Show (ex.Message);
    }
    }

  11. اضغط F5 لتشغيل التعليمات البرمجية، ثم انقر فوق
    File2OleDbBlob للتأكد من تحميل صورة موجودة في قاعدة بيانات SQL Server قبل محاولة كتابة إلى ملف.bmp على القرص.
العودة إلى أعلى

مجموعات القراءة من عمود BLOB

استخدام الدالات التالية عبارة SQL Server READTEXT و DataReader استرداد جزء من قيمة النقطة في مجموعة صفوف صف واحد أو عمود واحد. يتم استخدام هذين الأمرين: الأول استرداد حجم الحقل BLOB ومؤشر للموقع الخاص به؛ الثاني ينفذ الأمر READTEXT. الأمر READTEXT استرداد مجموعة البيانات في مصفوفة من وحدات بايت وزيادة إزاحة. تتم كتابة صفيف البايت إلى القرص من خلال الكائن System.IO.Filesream . عودة إلى الأعلى

كتابة مجموعات إلى عمود BLOB

استخدام الدالات التالية الكائنات الأمر و المعلمة وعبارة SQL Server UPDATETEXT لكتابة مجموعات البيانات من صفيف بايت إلى عمود BLOB. يتعذر العمود BLOB NULL باستخدام هذا الأسلوب، حيث يتم تعيين ببايت واحد إلى العمود قبل استرداد تيكستبتر. في أول تنفيذ عبارة UPDATETEXT، يتم تعيين DeleteParam.Value إلى 1. هذا حذف البايت الحالية من العمود قبل إدراج القطعة ومنع الذي من الحاجة بيانات غريبة الملحقة به. بيان UPDATETEXT تنفيذ عدة مرات، تزايد الإزاحة مع حجم المخزن المؤقت بعد كل استدعاء.
private void ChunkFile2SqlBlob(string SourceFilePath){
try
{
int BUFFER_LENGTH = 32768; // Chunk size.
SqlConnection cn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;");

// Make sure Photo is non-NULL and return TEXTPTR to it.

SqlCommand cmdGetPointer = new SqlCommand("SET NOCOUNT ON;UPDATE Categories SET Picture = 0x0 WHERE CategoryName='Test';" +
"SELECT @Pointer=TEXTPTR(Picture) FROM Categories WHERE CategoryName='Test'", cn);
SqlParameter PointerOutParam = cmdGetPointer.Parameters.Add("@Pointer", SqlDbType.VarBinary, 100);
PointerOutParam.Direction = ParameterDirection.Output;
cn.Open();
cmdGetPointer.ExecuteNonQuery();

// Set up UPDATETEXT command, parameters, and open BinaryReader.

SqlCommand cmdUploadBinary = new SqlCommand("UPDATETEXT Categories.Picture @Pointer @Offset @Delete WITH LOG @Bytes", cn);
SqlParameter PointerParam = cmdUploadBinary.Parameters.Add("@Pointer", SqlDbType.Binary, 16);
SqlParameter OffsetParam= cmdUploadBinary.Parameters.Add("@Offset", SqlDbType.Int);
SqlParameter DeleteParam = cmdUploadBinary.Parameters.Add("@Delete", SqlDbType.Int);
DeleteParam.Value = 1; // delete 0x0 character
SqlParameter BytesParam = cmdUploadBinary.Parameters.Add("@Bytes", SqlDbType.Binary, BUFFER_LENGTH);
System.IO.FileStream fs = new System.IO.FileStream(SourceFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
int Offset = 0;
OffsetParam.Value = Offset;


// Read buffer full of data and execute UPDATETEXT statement.

Byte [] Buffer = br.ReadBytes(BUFFER_LENGTH);
while(Buffer.Length > 0)
{
PointerParam.Value = PointerOutParam.Value;
BytesParam.Value = Buffer;
cmdUploadBinary.ExecuteNonQuery();
DeleteParam.Value = 0; //Do not delete any other data.
Offset += Buffer.Length;
OffsetParam.Value = Offset;
Buffer = br.ReadBytes(BUFFER_LENGTH);
}

br.Close();
fs.Close();
cn.Close();
}
catch(SqlException ex)
{
MessageBox.Show (ex.Message);
}
}

public void ChunkFile2OleDbBlob(string SourceFilePath)
{
try
{
int BUFFER_LENGTH = 32768; // chunk size
OleDbConnection cn = new OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;");

// Make sure Photo is non-NULL and return TEXTPTR to it.

OleDbCommand cmdGetPointer = new OleDbCommand("SET NOCOUNT ON;UPDATE Categories SET Picture = 0x0 WHERE CategoryName='Test';" +
"SELECT ?=TEXTPTR(Picture) FROM Categories WHERE CategoryName='Test'", cn);
OleDbParameter PointerOutParam = cmdGetPointer.Parameters.Add("@Pointer", OleDbType.VarBinary, 100);
PointerOutParam.Direction = ParameterDirection.Output;
cn.Open();
cmdGetPointer.ExecuteNonQuery();

// Set up UPDATETEXT command, parameters, and open BinaryReader.

OleDbCommand cmdUploadBinary = new OleDbCommand("UPDATETEXT Categories.Picture ? ? ? WITH LOG ?", cn);
OleDbParameter PointerParam = cmdUploadBinary.Parameters.Add("@Pointer", OleDbType.Binary, 16);
OleDbParameter OffsetParam = cmdUploadBinary.Parameters.Add("@Offset", OleDbType.Integer);
OleDbParameter DeleteParam = cmdUploadBinary.Parameters.Add("@Delete", OleDbType.Integer);
DeleteParam.Value = 1; // delete 0x0 character
OleDbParameter BytesParam = cmdUploadBinary.Parameters.Add("@Bytes", OleDbType.Binary, BUFFER_LENGTH);
System.IO.FileStream fs = new System.IO.FileStream(SourceFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
int Offset= 0;
OffsetParam.Value = Offset;


// Read buffer full of data and execute UPDATETEXT statement.

Byte[] Buffer = br.ReadBytes(BUFFER_LENGTH);
while(Buffer.Length > 0)
{
PointerParam.Value = PointerOutParam.Value;
BytesParam.Value = Buffer;
cmdUploadBinary.ExecuteNonQuery();
DeleteParam.Value = 0;// Do not delete any other data.
Offset += Buffer.Length;
OffsetParam.Value = Offset;
Buffer = br.ReadBytes(BUFFER_LENGTH);
}

br.Close();
fs.Close();
cn.Close();
}
catch(OleDbException ex)
{
MessageBox.Show (ex.Message);
}
}

ملاحظات
  • التعليمات البرمجية الموضحة في هذه المقالة قد لا يناسب الاستخدام مقابل LongVarChar أو LongVarWChar الأعمدة دون تغيير.
  • يجب عليك تعديل سلسلة الاتصال وعبارات SQL لتتوافق مع الخادم الخاص بك. يجب عليك أيضا إضافة خطأ التحقق من الاستعلام بإرجاع أية سجلات.
  • READTEXT و UPDATETEXT تعتبر خاصة ب Microsoft SQL Server. قد يكون لديك أنظمة قاعدة البيانات المختلفة مماثلة الأوامر التي يمكنك استخدامها.
العودة إلى أعلى

المراجع

للحصول على معلومات إضافية حول كيفية قراءة وكتابه البيانات دون chunking، انقر فوق أرقام المقالات التالية لعرضها في "قاعدة المعارف ل Microsoft":

316887 كيفية قراءة وكتابة ملف من عمود النقطة باستخدام ADO.NET و Visual Basic.NET

317017 كيفية قراءة وكتابة ملف من عمود النقطة باستخدام ADO.NET و Visual c + +.NET

317016 كيفية قراءة وكتابة ملف إلى أو من عمود النقطة باستخدام ADO.NET و Visual C#.NET

لمزيد من المعلومات حول العمل مع النقط في ADO.NET، قم بزيارة موقع شبكة مطوري Microsoft (MSDN) التالي على الويب:
الحصول على قيم BLOB من قاعدة بيانات
http://msdn.microsoft.com/en-us/library/87z0hy49.aspx
العودة إلى أعلى
خصائص

رقم الموضوع: 317043 - آخر مراجعة: 19‏/01‏/2017 - المراجعة: 1

تعليقات