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, você pode usar as mesmas instruções Transact-SQL com suporte para trabalhar com varbinary(max)
dados 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 | Description |
---|---|
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. |