Das Lesen und Schreiben einer Datei und aus einer BLOB-Spalte mit chunking in ADO.NET und Visual c# .NET

SPRACHE AUSWÄHLEN SPRACHE AUSWÄHLEN
Artikel-ID: 317043 - Produkte anzeigen, auf die sich dieser Artikel bezieht
Eine Microsoft Visual Basic .NET Version dieses Artikels finden Sie unter 317034.
Eine Microsoft Visual C++ .NET Version dieses Artikels finden Sie unter 317044.
Alles erweitern | Alles schließen

Auf dieser Seite

Zusammenfassung

Dieser schrittweise aufgebaute Artikel beschreibt die verwenden Sie der Anweisungen READTEXT von Microsoft SQL Server und UPDATETEXT zum Lesen und Schreiben von Daten aus Spalten in einer Datenbanktabelle BLOB (LongVarBinary).

Aufgrund von Netzwerkeinschränkungen müssen Sie eine große BLOB-Datei in kleinere Segmente und Information die Abschnitte zusammen anstatt das ganze BLOB gleichzeitig eine Datei abrufen. Daten von ADO.NET-Anbietern verfügen jedoch nicht GetChunk und AppendChunk Methoden für die Datenzugriffsobjekt (DAO) und ActiveX Data Objects (ADO)- Recordset -Objekte verfügbar gemacht. Dieser Artikel beschreibt verschiedene Möglichkeiten zum Abrufen von Daten in kleinere Segmente.

Notizen :
  • Dieser Artikel enthält Beispiele für beide die SqlClient Data Provider und der OLE DB .NET Data Provider. Die einzigen Unterschiede, abgesehen von Klassennamen, sind die Verbindungszeichenfolgen und die Deklaration des SQL-Parameter. Das grundlegende Verfahren zum Abrufen von der Anweisungen READTEXT und UPDATETEXT ist identisch.
  • Der Test-Datensatz in der Kategorientabelle der Northwind-Beispieldatenbank nicht vorhanden ist. Müssen Sie den Server-Explorer oder einem anderen Tool zum Hinzufügen eines Datensatzes mit den Kategorienamen legen Sie auf Test . Nachdem Sie die folgenden Beispiele verwenden, möchten Sie möglicherweise aus der Datenbank diesen Datensatz zu entfernen. Um den Datensatz zu entfernen, geben Sie folgenden Befehl in SQL Query Analyzer und drücken Sie F5:
    use Northwind
    delete from Categories where CategoryName = 'Test'
    					

Requirements

Im folgenden werden die empfohlene Hardware, Software, Netzwerkinfrastruktur, Fähigkeiten und Kenntnisse und Service Packs, die erforderlich sind:
  • Microsoft Windows 2000 Professional, Windows 2000 Server, Windows 2000 Advanced Server oder Microsoft Windows NT 4.0 Server
  • Microsoft Visual Studio .NET
  • Microsoft SQL Server 7.0 oder höher
In diesem Artikel wird davon ausgegangen, dass Sie mit ADO.NET vertraut sind-Grundlagen und Syntax.

Create a project and add code

  1. Öffnen Sie den SQL Query Analyzer.
  2. Geben Sie den folgenden Befehl ein und drücken Sie F5 die Standarddatenbank zur Northwind-Datenbank zu ändern:
    use Northwind
  3. Geben Sie den folgenden Befehl ein und drücken Sie F5 zum Einfügen eines neuen Datensatzes der Categories-Tabelle der Northwind-Datenbank:
    Insert into categories(categoryname) values ('Test')
    Hinweis müssen Sie nur diesen Datensatz der Tabelle Kategorien hinzufügen, wenn Sie in diesem Beispiel verwenden, ohne die vorhandenen Daten in dieser Tabelle ändern möchten.
  4. Erstellen Sie in Visual Studio .NET ein neues Visual c# .NET Windows-Anwendungsprojekt.
  5. Eine Anfang der Datei Form1.cs, fügen Sie die folgenden zwei Zeilen von Code, um Ihrem Projekt Verweise für System.Data.SQLClient und System.Data.OleDb hinzuzufügen:
    using System.Data.SqlClient;
    using System.Data.OleDb;
  6. Fügen Sie vier Schaltflächen zu Form1 hinzu. Ändern Sie die Text -Eigenschaft der Schaltflächen bzw. in SQLBlob2File , OlDbBlob2File , File2OleDbBlob und File2SqlBlob .
  7. Fügen Sie die folgende Zeichenfolge Variable Deklarationen unter der öffentlichen Klasse Form1:
    string destfilepath;
    string sourcefilepath;
    					
  8. Fügen Sie folgenden Code unter das Form Load -Ereignis:
    destfilepath = @"c:\mytest.bmp";
    sourcefilepath = @"c:\windows\coffee bean.bmp";
    					
  9. Rufen Sie die Prozeduren in das Click -Ereignis für jede Schaltfläche:
    // 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. Fügen Sie die folgenden vier Funktionen in 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. Drücken Sie F5, um den Code auszuführen, und klicken Sie auf File2OleDbBlob , um sicherzustellen, dass ein Bild in der SQL Server-Datenbank, laden bevor Sie versuchen, eine .bmp-Datei auf der Festplatte zu schreiben, aus.

Read chunks from a BLOB column

Die folgenden Funktionen verwenden Sie die SQL Server READTEXT-Anweisung und DataReader um einen Teil der BLOB-Wert in eine einzelne Zeile und einer Spalte Rowset abzurufen. Zwei Befehle verwendet werden: die erste Ruft die Größe des BLOB-Feld und einen Zeiger auf die Position ab; das zweite führt die READTEXT Befehl. READTEXT-Befehl ruft das Fragment der Daten in ein Bytearray und erhöht einen Offset. Das Bytearray wird auf den Datenträger über die System.IO.Filesream -Objekt geschrieben.

Write chunks to a BLOB column

Die folgenden Funktionen verwenden Sie die Befehle und Parameter -Objekte und der SQL Server UPDATETEXT-Anweisung, um Datenblöcke aus einem Bytearray in eine BLOB-Spalte zu schreiben. BLOB-Spalte darf nicht NULL mit dieser Methode sein, damit ein einzelnes Byte der Spalte zugewiesen ist, bevor TEXTPTR abgerufen wird. Bei der ersten Ausführung der UPDATETEXT-Anweisung wird die DeleteParam.Value auf 1 festgelegt. Dies löscht das vorhandene Byte aus der Spalte vor dem Einfügen der Abschnitt und verhindert, dass das BLOB überflüssige Daten angehängt. Die UPDATETEXT-Anweisung ist ausgeführten mehrmals, inkrementieren nach jedem Aufruf der-Offset mit der Größe des Puffers.
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);
   }
}
				
Notizen
  • Der Code, der in diesem Artikel beschrieben ist möglicherweise nicht für die Verwendung mit LongVarChar oder LongVarWChar Spalten ohne Änderung geeignet.
  • Sie müssen die Verbindungszeichenfolge und SQL-Anweisungen entsprechen, Ihren eigenen Server ändern. Sie müssen auch hinzufügen, Fehlerüberprüfung Wenn Ihre Abfrage keine Datensätze zurückgibt.
  • READTEXT und UPDATETEXT sind spezifisch für Microsoft SQL Server. Anderen Datenbanksystemen verfügen ähnliche Befehle, die Sie verwenden können.

Informationsquellen

Zusätzliche Informationen zum Lesen und schreiben Daten ohne chunking finden Sie in den folgenden Artikeln der Microsoft Knowledge Base:
316887Das Lesen und Schreiben einer Datei und aus einer BLOB-Spalte mithilfe von ADO.NET und Visual Basic .NET
317017Das Lesen und Schreiben eine Datei mithilfe von ADO.NET und Visual C++ .NET und aus einer BLOB-Spalte
317016Wie Sie lesen und Schreiben eine Datei oder von einer BLOB-Spalte mithilfe von ADO.NET und Visual c# .NET
Weitere Informationen zum Arbeiten mit BLOBs in ADO.NET der folgenden Microsoft Developer Network (MSDN)-Website:
Abrufen von BLOB-Werten aus einer Datenbank
http://msdn.microsoft.com/en-us/library/87z0hy49.aspx

Eigenschaften

Artikel-ID: 317043 - Geändert am: Mittwoch, 27. Oktober 2004 - Version: 3.3
Die Informationen in diesem Artikel beziehen sich auf:
  • Microsoft ADO.NET (included with the .NET Framework)
  • Microsoft ADO.NET 1.1
  • Microsoft Visual C# .NET 2002 Standard Edition
  • Microsoft Visual C# .NET 2003 Standard Edition
Keywords: 
kbmt kbsystemdata kbsqlclient kbhowtomaster KB317043 KbMtde
Maschinell übersetzter Artikel
Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.
Den englischen Originalartikel können Sie über folgenden Link abrufen: 317043
Microsoft stellt Ihnen die in der Knowledge Base angebotenen Artikel und Informationen als Service-Leistung zur Verfügung. Microsoft übernimmt keinerlei Gewährleistung dafür, dass die angebotenen Artikel und Informationen auch in Ihrer Einsatzumgebung die erwünschten Ergebnisse erzielen. Die Entscheidung darüber, ob und in welcher Form Sie die angebotenen Artikel und Informationen nutzen, liegt daher allein bei Ihnen. Mit Ausnahme der gesetzlichen Haftung für Vorsatz ist jede Haftung von Microsoft im Zusammenhang mit Ihrer Nutzung dieser Artikel oder Informationen ausgeschlossen.

Ihr Feedback an uns

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com