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 z dodatkiem SP1 (lub nowszym), aby pracować z danymi FILESTREAM.

Określenie atrybutu FILESTREAM w kolumnie varbinary(max) 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 danymi varbinary(max), które są przechowywane 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 FileOptionsSequentialScan.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 SqlFileStreamelement , ustawiając FileAccessWrite wartość na i na FileOptionsSequentialScan. Pojedynczy bajt jest zapisywany w SqlFileStreampliku , 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 SqlFileStreamelement , ustawiając FileAccessReadWrite wartość na i na FileOptionsSequentialScan. 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("server=(local);integrated security=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();
            }

        }
    }
}

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.

Zobacz też