Cómo leer y escribir un archivo a y desde una columna BLOB utilizando la fragmentación en ADO.NET y Visual C# .NET

Seleccione idioma Seleccione idioma
Id. de artículo: 317043 - Ver los productos a los que se aplica este artículo
Para obtener una versión de Microsoft Visual Basic .NET de este artículo, consulte 317034.
Para obtener una versión de Microsoft Visual C++ .NET de este artículo, consulte 317044.
Expandir todo | Contraer todo

En esta página

Resumen

en este artículo se describe paso a paso cómo utilizar las instrucciones READTEXT y UPDATETEXT de Microsoft SQL Server para leer y escribir datos de y en columnas BLOB (LongVarBinary) en una tabla de una base de datos.

Debido a restricciones de red, de tiene que recuperar un gran archivo BLOB en fragmentos más pequeños y, a continuación, parte los fragmentos juntos en lugar de recuperar el BLOB completo del archivo a la vez. Sin embargo, los proveedores de datos de ADO.NET no tienen métodos de GetChunk y AppendChunk disponibles para el objeto de acceso a datos (DAO) y objetos Recordset de ActiveX Data Objects (ADO). Este artículo describe diferentes formas de recuperar datos en fragmentos más pequeños.

notas :
  • Este artículo contiene ejemplos para SqlClient Data proveedor y el proveedor de datos .NET de OLE DB. Aprate de los nombres de las clases, la única diferencia entre ellas son las cadenas de conexión y la declaración de los parámetros SQL. Básicamente, la técnica que se debe utilizar para recuperar las instrucciones READTEXT y UPDATETEXT es la misma.
  • El registro Test de la tabla Categories de la base de datos de ejemplo Northwind no existe. Debe utilizar el Explorador de servidores o otra herramienta para agregar un registro con el NombreCategoría sea de prueba . Después de utilizar los siguientes ejemplos, desea quitar este registro de la base de datos. Para quitar el registro, escriba el comando siguiente en el Analizador de consultas SQL y, a continuación, presione F5:
    use Northwind
    delete from Categories where CategoryName = 'Test'
    					

Requirements

Los elementos siguientes describen el hardware recomendado, software, infraestructura de red, conocimientos y conocimientos y service Pack que son necesarios:
  • Microsoft Windows 2000 Professional, Windows 2000 Server, Windows 2000 Advanced Server o Microsoft Windows NT 4.0 Server
  • Microsoft Visual Studio .NET
  • Microsoft SQL Server 7.0 o posterior
Este artículo se supone que está familiarizado con ADO.NET Fundamentos y sintaxis.

Create a project and add code

  1. Abrir el Analizador de consultas de SQL.
  2. Escriba el comando siguiente y presione F5 para cambiar la base de datos predeterminada a Northwind:
    use Northwind
  3. Escriba el comando siguiente y presione F5 para insertar un nuevo registro en la tabla Categories de la base de datos Northwind:
    Insert into categories(categoryname) values ('Test')
    Nota , sólo tiene que agregar este registro a la tabla Categorías si desea utilizar este ejemplo sin modificarlos datos existentes en esta tabla.
  4. En Visual Studio. NET, cree un nuevo Windows de .NET de Visual C# proyecto de aplicación.
  5. Principio de los límites del archivo Form1.cs, agregue las siguientes dos líneas de código para agregar referencias al proyecto para System.Data.SqlClient y System.Data.SqlClient :
    using System.Data.SqlClient;
    using System.Data.OleDb;
  6. Agregue cuatro botones a Form1. Cambie la propiedad Text de los botones a SQLBlob2File , OlDbBlob2File , File2OleDbBlob y File2SqlBlob , respectivamente.
  7. Agregue las siguiente declaraciones de variable de cadena en la clase pública Form1:
    string destfilepath;
    string sourcefilepath;
    					
  8. Pegue el código siguiente en el evento Load del formulario:
    destfilepath = @"c:\mytest.bmp";
    sourcefilepath = @"c:\windows\coffee bean.bmp";
    					
  9. Llamar a los procedimientos en el evento Click para cada botón:
    // 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. Pegue las cuatro funciones siguientes en 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. Presione F5 para ejecutar el código y, a continuación, haga clic en File2OleDbBlob para asegurarse de que se carga una imagen en la base de datos SQL Server antes de intentar escribir en un archivo .bmp en el disco.

Read chunks from a BLOB column

Las siguientes funciones utilizan la instrucción READTEXT de SQL Server y el DataReader para recuperar una parte del valor BLOB de un conjunto de filas única fila y columna único. Se utilizan dos comandos: el primero recupera el tamaño del campo BLOB y un puntero a su ubicación; el segundo ejecuta el READTEXT comandos. El comando READTEXT, recupera el fragmento de datos en una matriz de bytes y incrementa un desplazamiento. La matriz de bytes se escribe en el disco a través de la System.IO.FileStream objeto.

Write chunks to a BLOB column

Las siguientes funciones utilizan los objetos Command y Parameter y la instrucción UPDATETEXT de SQL Server para escribir fragmentos de datos de una matriz de bytes en una columna BLOB. La columna BLOB no puede ser NULL con este método para que un solo byte se asigna a la columna antes de recupera TEXTPTR. En la primera ejecución de la instrucción UPDATETEXT, DeleteParam.Value está establecida a 1. Esto elimina el byte existente de la columna antes de insertar el fragmento y evita que el BLOB tener datos extraños anexadas al mismo. La instrucción UPDATETEXT es ejecutado varias veces, incremento de desplazamiento con el tamaño del búfer después de cada llamada.
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);
   }
}
				
notas
  • El código que se describe en este artículo no puede ser adecuado para su uso en las columnas tipo LongVarChar o LongVarWChar sin modificación.
  • Debe modificar la cadena de conexión y las instrucciones de SQL que se correspondan con su propio servidor. También debe agregar error comprobar si la consulta no devuelve ningún registro.
  • READTEXT y UPDATETEXT son instrucciones específicas de Microsoft SQL Server. Los sistemas de base de datos diferentes pueden tener comandos similares que se pueden utilizar.

Referencias

Para obtener información adicional acerca de cómo leer y escribir datos sin fragmentar, haga clic en los números de artículo siguientes para verlos en Microsoft Knowledge Base:
316887Cómo leer y escribir un archivo a y desde una columna BLOB utilizando ADO.NET y Visual Basic .NET
317017Cómo leer y escribir un archivo a y desde una columna BLOB utilizando ADO.NET y Visual C++ .NET
317016Cómo leer y escribir un archivo a o desde una columna BLOB utilizando ADO.NET y Visual C# .NET
Para obtener más información sobre cómo trabajar con BLOB en ADO.NET, visite el siguiente sitio Web de Microsoft Developer Network (MSDN):
Obtención de valores BLOB de una base de datos
http://msdn.microsoft.com/en-us/library/87z0hy49.aspx

Propiedades

Id. de artículo: 317043 - Última revisión: miércoles, 27 de octubre de 2004 - Versión: 3.3
La información de este artículo se refiere a:
  • 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
Palabras clave: 
kbmt kbsystemdata kbsqlclient kbhowtomaster KB317043 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 317043

Enviar comentarios

 

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