Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O atributo de armazenamento FILESTREAM é para dados binários (BLOB) armazenados numa coluna varbinary(max). Antes do FILESTREAM, armazenar dados binários exigia um tratamento especial. Dados não estruturados, como documentos de texto, imagens e vídeo, são frequentemente armazenados fora da base de dados, dificultando a sua gestão.
Observação
Deve instalar o .NET Framework 3.5 SP1 (ou posterior) ou o .NET Core para trabalhar com dados FILESTREAM usando SqlClient.
Especificar o atributo FILESTREAM numa coluna varbinary(max) faz com que o SQL Server armazene os dados no sistema de ficheiros NTFS local em vez de no ficheiro da base de dados. Embora esteja armazenado separadamente, pode usar as mesmas instruções Transact-SQL suportadas para trabalhar com dados do tipo varbinary(max) armazenados na base de dados.
Suporte SqlClient para FILESTREAM
O Microsoft SqlClient Data Provider para SQL Server, Microsoft.Data.SqlClient, suporta a leitura e escrita de dados FILESTREAM usando a SqlFileStream classe definida no System.Data.SqlTypes namespace.
SqlFileStream herda da Stream classe, que fornece métodos para leitura e escrita em fluxos de dados. A leitura de um fluxo transfere dados do fluxo para uma estrutura de dados, como um array de bytes. A escrita transfere os dados da estrutura de dados para um fluxo.
Criação da tabela SQL Server
As seguintes instruções Transact-SQL criam uma tabela chamada funcionários e inserem uma linha de dados. Depois de ativar o armazenamento FILESTREAM, pode usar esta tabela com os exemplos de código que se seguem. Os links para recursos no SQL Server Books Online encontram-se no final deste artigo.
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: Ler, sobrescrever e inserir dados do FILESTREAM
O exemplo seguinte demonstra como ler dados de um FILESTREAM. O código obtém o caminho lógico para o ficheiro, definindo o FileAccess para Read e o FileOptions para SequentialScan. O código então lê os bytes do SqlFileStream para o buffer. Os bytes são então escritos na janela da consola.
O exemplo também demonstra como escrever dados num FILESTREAM em que todos os dados existentes são sobrescritos. O código obtém o caminho lógico até ao ficheiro e cria o SqlFileStream, definindo o FileAccess to Write e o FileOptions to SequentialScan. Um único byte é escrito no SqlFileStream, substituindo quaisquer dados no ficheiro.
O exemplo também demonstra como escrever dados num FILESTREAM usando o método Seek para anexar dados ao final do ficheiro. O código obtém o caminho lógico até ao ficheiro e cria o SqlFileStream, definindo o FileAccess to ReadWrite e o FileOptions to SequentialScan. O código utiliza o método Seek para procurar até ao final do ficheiro, acrescentando um único byte ao ficheiro existente.
using System;
using Microsoft.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("server=(local);integrated security=true;Encrypt=True;database=myDB");
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 outro exemplo, veja Como armazenar e buscar dados binários numa coluna de fluxo de ficheiros.
Recursos em SQL Server Books Online
A documentação completa do FILESTREAM encontra-se nas secções seguintes do SQL Server Books Online.
| Artigo | Description |
|---|---|
| FILESTREAM (SQL Server) | Descreve quando usar o armazenamento FILESTREAM e como este integra o Motor de Base de Dados SQL Server com um sistema de ficheiros NTFS. |
| Criar aplicativos cliente para dados FILESTREAM | Descreve as funções da API do Windows para trabalhar com dados do FILESTREAM. |
| FILESTREAM e Outras Funcionalidades do SQL Server | Fornece considerações, orientações e limitações para a utilização de dados FILESTREAM com outras funcionalidades do SQL Server. |