Partilhar via


Dados FILESTREAM

O atributo de armazenamento FILESTREAM é para dados binários (BLOB) armazenados em uma varbinary(max) coluna. Antes do FILESTREAM, o armazenamento de dados binários exigia um tratamento especial. Dados não estruturados, como documentos de texto, imagens e vídeos, geralmente são armazenados fora do banco de dados, dificultando o gerenciamento.

Nota

Você deve instalar o .NET Framework 3.5 SP1 (ou posterior) para trabalhar com dados FILESTREAM usando SqlClient.

Especificar o atributo FILESTREAM em uma varbinary(max) coluna faz com que o SQL Server armazene os dados no sistema de arquivos NTFS local em vez de no arquivo de banco de dados. Embora seja armazenado separadamente, pode-se usar as mesmas instruções Transact-SQL que são compatíveis para trabalhar com dados varbinary(max) armazenados no banco de dados.

Suporte SqlClient para FILESTREAM

O Provedor de Dados do .NET Framework para SQL Server, System.Data.SqlClient, oferece suporte à leitura e gravação em dados FILESTREAM usando a SqlFileStream classe definida no System.Data.SqlTypes namespace. SqlFileStream Herda da Stream classe, que fornece métodos para leitura e gravação em fluxos de dados. A leitura de um fluxo transfere dados do fluxo para uma estrutura de dados, como uma matriz de bytes. A gravação transfere os dados da estrutura de dados para um fluxo.

Criando a tabela do SQL Server

As instruções Transact-SQL a seguir criam uma tabela chamada employees e inserem uma linha de dados. Depois de habilitar o armazenamento FILESTREAM, você pode usar esta tabela em conjunto com os exemplos de código a seguir.

CREATE TABLE employees
(
  EmployeeId INT  NOT NULL  PRIMARY KEY,
  Photo VARBINARY(MAX) FILESTREAM  NULL,
  RowGuid UNIQUEIDENTIFIER  NOT NULL  ROWGUIDCOL
  UNIQUE DEFAULT NEWID()
)
GO
Insert into employees
Values(1, 0x00, default)
GO

Exemplo: leitura, substituição e inserção de dados FILESTREAM

O exemplo a seguir demonstra como ler dados de um FILESTREAM. O código obtém o caminho lógico para o arquivo, definindo o FileAccess para Read e o FileOptions para SequentialScan. O código, em seguida, lê os bytes do SqlFileStream para o buffer. Os bytes são então gravados na janela do console.

O exemplo também demonstra como gravar dados em um FILESTREAM no qual todos os dados existentes são substituídos. O código obtém o caminho lógico para o arquivo e cria o SqlFileStream, definindo o FileAccess para Write e o FileOptions para SequentialScan. Um único byte é gravado no SqlFileStream, substituindo quaisquer dados no arquivo.

O exemplo também demonstra como gravar dados em um FILESTREAM usando o método Seek para acrescentar dados ao final do arquivo. O código obtém o caminho lógico para o arquivo e cria o SqlFileStream, definindo o FileAccess para ReadWrite e o FileOptions para SequentialScan. O código usa o método Seek para procurar até o final do arquivo, anexando um único byte ao arquivo existente.

using System;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Data;
using System.IO;

namespace FileStreamTest
{
    class Program
    {
        static void Main(string[] args)
        {
            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder("...");
            ReadFileStream(builder);
            OverwriteFileStream(builder);
            InsertFileStream(builder);

            Console.WriteLine("Done");
        }

        private static void ReadFileStream(SqlConnectionStringBuilder connStringBuilder)
        {
            using (SqlConnection connection = new SqlConnection(connStringBuilder.ToString()))
            {
                connection.Open();
                SqlCommand command = new SqlCommand("SELECT TOP(1) Photo.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM employees", connection);

                SqlTransaction tran = connection.BeginTransaction(IsolationLevel.ReadCommitted);
                command.Transaction = tran;

                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        // Get the pointer for the file
                        string path = reader.GetString(0);
                        byte[] transactionContext = reader.GetSqlBytes(1).Buffer;

                        // Create the SqlFileStream
                        using (Stream fileStream = new SqlFileStream(path, transactionContext, FileAccess.Read, FileOptions.SequentialScan, allocationSize: 0))
                        {
                            // Read the contents as bytes and write them to the console
                            for (long index = 0; index < fileStream.Length; index++)
                            {
                                Console.WriteLine(fileStream.ReadByte());
                            }
                        }
                    }
                }
                tran.Commit();
            }
        }

        private static void OverwriteFileStream(SqlConnectionStringBuilder connStringBuilder)
        {
            using (SqlConnection connection = new SqlConnection(connStringBuilder.ToString()))
            {
                connection.Open();

                SqlCommand command = new SqlCommand("SELECT TOP(1) Photo.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM employees", connection);

                SqlTransaction tran = connection.BeginTransaction(IsolationLevel.ReadCommitted);
                command.Transaction = tran;

                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        // Get the pointer for file
                        string path = reader.GetString(0);
                        byte[] transactionContext = reader.GetSqlBytes(1).Buffer;

                        // Create the SqlFileStream
                        using (Stream fileStream = new SqlFileStream(path, transactionContext, FileAccess.Write, FileOptions.SequentialScan, allocationSize: 0))
                        {
                            // Write a single byte to the file. This will
                            // replace any data in the file.
                            fileStream.WriteByte(0x01);
                        }
                    }
                }
                tran.Commit();
            }
        }

        private static void InsertFileStream(SqlConnectionStringBuilder connStringBuilder)
        {
            using (SqlConnection connection = new SqlConnection(connStringBuilder.ToString()))
            {
                connection.Open();

                SqlCommand command = new SqlCommand("SELECT TOP(1) Photo.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM employees", connection);

                SqlTransaction tran = connection.BeginTransaction(IsolationLevel.ReadCommitted);
                command.Transaction = tran;

                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        // Get the pointer for file
                        string path = reader.GetString(0);
                        byte[] transactionContext = reader.GetSqlBytes(1).Buffer;

                        using (Stream fileStream = new SqlFileStream(path, transactionContext, FileAccess.ReadWrite, FileOptions.SequentialScan, allocationSize: 0))
                        {
                            // Seek to the end of the file
                            fileStream.Seek(0, SeekOrigin.End);

                            // Append a single byte
                            fileStream.WriteByte(0x01);
                        }
                    }
                }
                tran.Commit();
            }

        }
    }
}

Para obter outro exemplo, consulte Como armazenar e buscar dados binários em uma coluna de fluxo de arquivos.

Recursos de documentos do SQL Server

A documentação completa para FILESTREAM está localizada nas seguintes seções dos documentos do SQL Server.

Tópico Descrição
FILESTREAM (SQL Server) Descreve quando usar o armazenamento FILESTREAM e como ele integra o Mecanismo de Banco de Dados do SQL Server a um sistema de arquivos NTFS.
Criar aplicativos cliente para dados FILESTREAM Descreve as funções da API do Windows para trabalhar com dados FILESTREAM.
FILESTREAM e outros recursos do SQL Server Fornece considerações, diretrizes e limitações para usar dados FILESTREAM com outros recursos do SQL Server.

Consulte também