Como ler e escrever um ficheiro de e para uma coluna BLOB utilizando chunking no ADO.NET e Visual C# .NET

Traduções de Artigos Traduções de Artigos
Artigo: 317043 - Ver produtos para os quais este artigo se aplica.
Para obter uma Microsoft Visual Basic .NET versão deste artigo, consulte 317034.
Para obter uma versão de Microsoft Visual C++ .NET deste artigo, consulte 317044.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

Este artigo passo a passo descreve como utilizar as instruções do Microsoft SQL Server READTEXT e UPDATETEXT para ler e escrever dados do BLOB (LongVarBinary) colunas numa tabela da base de dados.

Devido a restrições de rede, poderá ter de obter um grande ficheiro BLOB em secções mais pequenas e, em seguida, peça blocos em conjunto em vez de obter o BLOB todo ficheiros em simultâneo. No entanto, ADO.NET fornecedores de dados não são necessário GetChunk e AppendChunk métodos disponíveis para o objecto de acesso a dados (DAO) e os objectos ActiveX Data Objects (ADO) conjunto de registos . Este artigo descreve diferentes formas de obter dados em secções mais pequenas.

notas :
  • Este artigo contém exemplos de dados SqlClient fornecedor e o OLE DB .NET Data Provider. As únicas diferenças, além dos nomes de classe, são as cadeias de ligação e a declaração de parâmetros de SQL. A técnica fundamental para obter as instruções READTEXT e UPDATETEXT é o mesmo.
  • O registo de teste na tabela Categorias de base de dados de exemplo não existe. Tem de utilizar o Explorador do servidor ou outra ferramenta para adicionar um registo com o NomeDaCategoria defina para teste . Depois de utilizar os exemplos seguintes, poderá remover este registo da base de dados. Para remover o registo, escreva o seguinte comando no SQL Query Analyzer e, em seguida, prima F5:
    use Northwind
    delete from Categories where CategoryName = 'Test'
    					

Requirements

Os seguintes itens descrevem o hardware recomendado, software, infra-estrutura de rede, competências e conhecimentos e service packs são necessários:
  • Microsoft Windows 2000 Professional, Windows 2000 Server, Windows 2000 Advanced Server ou Microsoft Windows NT 4.0 Server
  • Microsoft Visual Studio .NET
  • Microsoft SQL Server 7.0 ou posterior
Este artigo pressupõe que está familiarizado com o ADO.NET fundamentais e sintaxe.

Create a project and add code

  1. Abra o SQL Query Analyzer.
  2. Escreva o seguinte comando e prima F5 para alterar a base de dados predefinido para a base de dados Adamastor:
    use Northwind
  3. Escreva o seguinte comando e prima F5 para inserir um novo registo na tabela de base de dados Adamastor categorias:
    Insert into categories(categoryname) values ('Test')
    NOTA: apenas é necessário adicionar este registo à tabela de categorias se pretender utilizar este exemplo sem modificar os dados existentes nesta tabela.
  4. No Visual Studio. NET, crie um novo Visual C# .NET Windows projecto de aplicação.
  5. Athe parte superior do ficheiro Form1.cs, adicione as seguintes duas linhas de código para adicionar referências ao projecto para System.Data.SQLClient e System.data.OLEDB :
    using System.Data.SqlClient;
    using System.Data.OleDb;
  6. Adicione quatro botões ao Form1. Altere a propriedade texto dos botões para SQLBlob2File , OlDbBlob2File , File2OleDbBlob e File2SqlBlob , respectivamente.
  7. Adicionar as seguintes declarações de variáveis cadeia sob a classe pública Form1:
    string destfilepath;
    string sourcefilepath;
    					
  8. Cole o seguinte código sob o evento carregar do formulário:
    destfilepath = @"c:\mytest.bmp";
    sourcefilepath = @"c:\windows\coffee bean.bmp";
    					
  9. Chamam os procedimentos no evento Click para cada botão:
    // 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. Cole as seguintes quatro funções no 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. Prima F5 para executar o código e, em seguida, clique em File2OleDbBlob para se certificar de que carregar uma imagem numa base de dados do SQL Server antes de tentar escrever para um ficheiro .bmp no disco.

Read chunks from a BLOB column

As seguintes funções de utilizar a instrução de SQL Server READTEXT e DataReader para obter uma parte do valor BLOB um conjunto de linhas simples-linhas e colunas único. São utilizados dois comandos: a primeira obtém o tamanho do campo BLOB e um ponteiro para a localização; o segundo executa o READTEXT comandos. O comando READTEXT obtém o bloco de dados de uma matriz de bytes e incrementa um desvio. A matriz de bytes é escrita no disco através de System.IO.Filesream objecto

Write chunks to a BLOB column

As seguintes funções de utilizar os objectos de comandos e parâmetros e a instrução de SQL Server UPDATETEXT para escrever blocos de dados de uma matriz de bytes para uma coluna BLOB. A coluna BLOB não pode ser NULL com este método para que um único byte é atribuído a coluna antes TEXTPTR são obtidos. Na primeira execução da instrução UPDATETEXT, DeleteParam.Value está definido para 1. Isto elimina o byte existente da coluna antes de inserir a secção e impede que o BLOB ter dados irrelevantes anexados ao mesmo. A instrução UPDATETEXT é executada várias vezes, aumentando o deslocamento com o tamanho da memória intermédia depois de cada chamada. privada
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
  • O código que é descrito neste artigo pode não ser adequado para utilização contra LongVarChar ou LongVarWChar colunas sem modificações.
  • Tem de modificar a cadeia de ligação e instruções de SQL para corresponder ao seu próprio servidor. Também tem de adicionar verificação se a consulta não devolve nenhum registo de erros.
  • READTEXT e UPDATETEXT são específicos do Microsoft SQL Server. Sistemas de base de dados diferente poderão ter semelhantes comandos que podem ser utilizados.

Referências

Para obter informações adicionais sobre como ler e escrever dados sem chunking, clique números de artigo que se seguem para visualizar os artigos na base de dados de conhecimento da Microsoft:
316887Como ler e escrever um ficheiro de e para uma coluna BLOB utilizando o ADO.NET e Visual Basic .NET
317017Como ler e escrever um ficheiro de e para uma coluna BLOB utilizando o ADO.NET e Visual C++ .NET
317016Como ler e escrever um ficheiro ou para uma coluna BLOB utilizando o ADO.NET e Visual C# .NET
Para mais informações sobre como trabalhar com BLOBs no ADO.NET, visite o seguinte Web site da Microsoft Developer Network (MSDN):
Obter BLOB valores de uma base de dados
http://msdn.microsoft.com/en-us/library/87z0hy49.aspx

Propriedades

Artigo: 317043 - Última revisão: 27 de outubro de 2004 - Revisão: 3.3
A informação contida neste artigo aplica-se 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
Palavras-chave: 
kbmt kbsystemdata kbsqlclient kbhowtomaster KB317043 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 317043

Submeter comentários

 

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