Данные FILESTREAM в SQL Server 2008 (ADO.NET)
В SQL Server 2008 для двоичных (BLOB) данных, хранящихся в столбце varbinary(max), появился новый атрибут хранилища FILESTREAM. В SQL Server всегда можно было хранить двоичные данные, однако для работы с ними требовалась специальная обработка. Неструктурированные данные, например текстовые документы, изображения и видеоролики, зачастую хранятся вне базы данных, что затрудняет работу с ними.
Примечание |
---|
Для работы с данными FILESTREAM через SqlClient необходимо установить .NET Framework 3.5 с пакетом обновления 1 (SP1) или более поздней версии. |
При указании для столбца varbinary(max) атрибута FILESTREAM сервер SQL Server сохраняет данные не в файле базы данных, а в файловой системе NTFS на локальном компьютере. Хотя эти данные хранятся отдельно, для работы с ними можно использовать те же инструкции Transact-SQL, что и для данных varbinary(max), хранящихся в базе данных.
Поддержка атрибута FILESTREAM в SqlClient
Поставщик данных .NET Framework для SQL Server (System.Data.SqlClient) поддерживает чтение и запись данных FILESTREAM с помощью класса SqlFileStream, определенного в пространстве имен System.Data.SqlTypes. Класс SqlFileStream является производным от класса System.IO.Stream, который содержит методы для чтения и записи потоков данных. При чтении из потока данные передаются в структуру данных, например в массив байтов. При записи данные передаются из структуры данных в поток.
Создание таблицы SQL Server
Приведенная ниже инструкция Transact-SQL создает таблицу employees и вставляет в нее строку данных. После включения атрибута FILESTREAM эту таблицу можно использовать в приведенных ниже примерах кода. Ссылки на ресурсы электронной документации по SQL Server 2008 приведены в конце данного раздела.
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
Пример чтения данных FILESTREAM
В приведенном ниже фрагменте кода демонстрируется чтение данных из потока FILESTREAM. В коде определяется логический путь к файлу, свойству FileAccess присваивается значение Read, а свойству FileOptions — значение SequentialScan. Затем в коде считываются в буфер байты данных из потока SqlFileStream. Эти байты данных затем выводятся в окно консоли.
using (SqlConnection connection = new SqlConnection(
connStringBuilder.ToString()))
{
connection.Open();
SqlCommand command = new SqlCommand("", connection);
SqlTransaction tran = connection.BeginTransaction(
System.Data.IsolationLevel.ReadCommitted);
command.Transaction = tran;
command.CommandText =
"select Top(1) Photo.PathName(), "
+ "GET_FILESTREAM_TRANSACTION_CONTEXT () from employees";
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
FileStream fileStream = new SqlFileStream(path,
(byte[])reader.GetValue(1),
FileAccess.Read,
FileOptions.SequentialScan, 0);
// Read the contents as bytes and write them to the console
for (long index = 0; index < fileStream.Length; index++)
{
Console.Write(fileStream.ReadByte());
}
fileStream.Close();
}
}
tran.Commit();
}
Пример перезаписи данных FILESTREAM
В приведенном ниже фрагменте кода демонстрируется запись данных в поток FILESTREAM с перезаписью всех существующих данных. В коде определяется логический путь к файлу, создается поток SqlFileStream, свойству FileAccess присваивается значение Write, а свойству FileOptions — значение SequentialScan. В поток SqlFileStream записывается один байт, заменяющий все данные в файле.
using (SqlConnection connection = new SqlConnection(
connStringBuilder.ToString()))
{
connection.Open();
SqlCommand command = new SqlCommand("", connection);
command.CommandText = "select Top(1) Photo.PathName(), "
+ "GET_FILESTREAM_TRANSACTION_CONTEXT () from employees";
SqlTransaction tran = connection.BeginTransaction(
System.Data.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
FileStream fileStream = new SqlFileStream(path,
(byte[])reader.GetValue(1),
FileAccess.Write,
FileOptions.SequentialScan, 0);
// Write a single byte to the file. This will
// replace any data in the file.
fileStream.WriteByte(0x01);
fileStream.Close();
}
}
tran.Commit();
}
Пример вставки данных FILESTREAM
В приведенном ниже примере кода демонстрируется запись данных в поток FILESTREAM с использованием метода Seek для добавления данных в конец файла. В коде определяется логический путь к файлу, создается поток SqlFileStream, свойству FileAccess присваивается значение ReadWrite, а свойству FileOptions — значение SequentialScan. Для поиска конца файла в коде используется метод Seek, после чего в конец файла добавляется один байт.
using (SqlConnection connection = new SqlConnection(
connStringBuilder.ToString()))
{
connection.Open();
SqlCommand command = new SqlCommand("", connection);
command.CommandText = "select Top(1) Photo.PathName(), "
+ "GET_FILESTREAM_TRANSACTION_CONTEXT () from employees";
SqlTransaction tran = connection.BeginTransaction(
System.Data.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;
FileStream fileStream = new SqlFileStream(path,
(byte[])reader.GetValue(1),
FileAccess.ReadWrite,
FileOptions.SequentialScan, 0);
// Seek to the end of the file
fs.Seek(0, SeekOrigin.End);
// Append a single byte
fileStream.WriteByte(0x01);
fileStream.Close();
}
}
tran.Commit();
}
Ресурсы электронной документации по SQL Server
Полная документация по FILESTREAM содержится в указанных ниже разделах электронной документации по SQL Server 2008.
Раздел |
Описание |
---|---|
Приводятся ссылки на документацию по атрибуту FILESTREAM и связанные с ним разделы. |
|
Приводятся сведения о том, когда необходимо использовать хранилище FILESTREAM; также описывается интеграция ядра СУБД SQL Server и файловой системы NTFS. |
|
Описывается включение хранилища FILESTREAM для экземпляра SQL Server, создание базы данных и таблицы, в которой будут храниться данные FILESTREAM, а также работа со строками, содержащими данные FILESTREAM. |
|
Описываются функции API-интерфейса Win32, предназначенные для работы с данными FILESTREAM. |
|
Приводятся общие сведения, рекомендации и ограничения при использовании данных FILESTREAM совместно с другими возможностями SQL Server. |
См. также
Основные понятия
Управление доступом для кода и ADO.NET
Другие ресурсы
Типы данных SQL Server и ADO.NET
Получение и изменение данных в ADO.NET
Двоичные данные и данные большого размера SQL Server (ADO.NET)