DANE FILESTREAM
Atrybut magazynu FILESTREAM jest przeznaczony dla danych binarnych (BLOB) przechowywanych w kolumnie varbinary(max)
. Przed fileSTREAM przechowywanie danych binarnych wymaga specjalnej obsługi. Dane bez struktury, takie jak dokumenty tekstowe, obrazy i wideo, są często przechowywane poza bazą danych, co utrudnia zarządzanie.
Uwaga
Aby pracować z danymi FILESTREAM, należy zainstalować program .NET Framework 3.5 SP1 (lub nowszy) przy użyciu programu SqlClient.
Określenie atrybutu FILESTREAM w varbinary(max)
kolumnie powoduje, że program SQL Server będzie przechowywać dane w lokalnym systemie plików NTFS zamiast w pliku bazy danych. Mimo że jest on przechowywany oddzielnie, można użyć tych samych instrukcji języka Transact-SQL, które są obsługiwane do pracy z varbinary(max)
danymi przechowywanymi w bazie danych.
Obsługa elementu SQLClient dla elementu FILESTREAM
Program .NET Framework Dostawca danych dla programu SQL Server System.Data.SqlClientobsługuje odczytywanie i zapisywanie danych FILESTREAM przy użyciu SqlFileStream klasy zdefiniowanej System.Data.SqlTypes w przestrzeni nazw. SqlFileStream
dziedziczy z Stream klasy , która udostępnia metody odczytywania i zapisywania strumieni danych. Odczyt ze strumienia przesyła dane ze strumienia do struktury danych, takiej jak tablica bajtów. Zapisywanie transferuje dane ze struktury danych do strumienia.
Tworzenie tabeli programu SQL Server
Poniższe instrukcje języka Transact-SQL tworzą tabelę o nazwie employees i wstawia wiersz danych. Po włączeniu magazynu FILESTREAM możesz użyć tej tabeli w połączeniu z poniższymi przykładami kodu.
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
Przykład: odczytywanie, zastępowanie i wstawianie danych FILESTREAM
W poniższym przykładzie pokazano, jak odczytywać dane z elementu FILESTREAM. Kod pobiera ścieżkę logiczną do pliku, ustawiając wartość na FileAccess
i na FileOptions
SequentialScan
.Read
Następnie kod odczytuje bajty z elementu SqlFileStream do buforu. Bajty są następnie zapisywane w oknie konsoli.
W przykładzie pokazano również, jak zapisywać dane w obiekcie FILESTREAM, w którym wszystkie istniejące dane są zastępowane. Kod pobiera ścieżkę logiczną do pliku i tworzy SqlFileStream
element , ustawiając FileAccess
Write
wartość na i na FileOptions
SequentialScan
. Pojedynczy bajt jest zapisywany w SqlFileStream
pliku , zastępując wszystkie dane w pliku.
W przykładzie pokazano również, jak zapisywać dane w pliku FILESTREAM przy użyciu metody Seek w celu dołączenia danych na końcu pliku. Kod pobiera ścieżkę logiczną do pliku i tworzy SqlFileStream
element , ustawiając FileAccess
ReadWrite
wartość na i na FileOptions
SequentialScan
. Kod używa metody Seek do wyszukiwania na końcu pliku, dołączając pojedynczy bajt do istniejącego pliku.
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();
}
}
}
}
Aby zapoznać się z innym przykładem, zobacz Jak przechowywać i pobierać dane binarne do kolumny strumienia plików.
Zasoby dokumentacji programu SQL Server
Pełna dokumentacja pliku FILESTREAM znajduje się w poniższych sekcjach dokumentacji programu SQL Server.
Temat | opis |
---|---|
FILESTREAM (SQL Server) | Opisuje, kiedy używać magazynu FILESTREAM i jak integruje aparat bazy danych programu SQL Server z systemem plików NTFS. |
Tworzenie aplikacji klienckich dla danych FILESTREAM | Opisuje funkcje interfejsu API systemu Windows do pracy z danymi FILESTREAM. |
FILESTREAM i inne funkcje programu SQL Server | Zawiera zagadnienia, wskazówki i ograniczenia dotyczące używania danych FILESTREAM z innymi funkcjami programu SQL Server. |