Udostępnij przez


DANE FILESTREAM

Pobieranie ADO.NET

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 / Notatka

Aby pracować z danymi FILESTREAM, należy zainstalować program .NET Framework 3.5 z dodatkiem SP1 (lub nowszym) lub .NET Core.

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 Transact-SQL, które są obsługiwane do pracy z danymi varbinary(max), które są przechowywane w bazie danych.

Obsługa SQLClient dla FILESTREAM

Dostawca danych Microsoft SqlClient dla SQL Server Microsoft.Data.SqlClient obsługuje odczytywanie i zapisywanie danych FILESTREAM przy użyciu klasy SqlFileStream, zdefiniowanej w przestrzeni nazw System.Data.SqlTypes. 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 Transact-SQL tworzą tabelę o nazwie employees i wstawia wiersz danych. Po włączeniu magazynu FILESTREAM możesz użyć tej tabeli ze znajdującymi się poniżej przykładami kodu. Linki do zasobów w książkach programu SQL Server Online znajdują się na końcu tego artykułu.

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

Poniższy przykład demonstruje, jak odczytywać dane z FILESTREAM. Kod pobiera ścieżkę logiczną do pliku, ustawiając FileAccess na Read i FileOptions na SequentialScan. 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 strumieniu FILESTREAM, w którym wszystkie istniejące dane są nadpisywane. Kod pobiera ścieżkę logiczną do pliku i tworzy element SqlFileStream, ustawiając FileAccess na Write oraz FileOptions na SequentialScan. 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 uzyskuje logiczną ścieżkę do pliku i tworzy element SqlFileStream, ustawiając FileAccess na ReadWrite oraz FileOptions na SequentialScan. Kod używa metody Seek do wyszukiwania na końcu pliku, dołączając pojedynczy bajt do istniejącego pliku.

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();
            }

        }
    }
}

Aby zapoznać się z innym przykładem, zobacz Jak przechowywać i pobierać dane binarne do kolumny strumienia plików.

Zasoby w książkach programu SQL Server Online

Pełna dokumentacja funkcji FILESTREAM znajduje się w poniższych sekcjach w książkach programu SQL Server Online.

Article Description
FILESTREAM (SQL Server) Opisuje, kiedy stosować magazyn FILESTREAM oraz jak integruje silnik bazy danych 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, wytyczne i ograniczenia dotyczące używania danych FILESTREAM z innymi funkcjami programu SQL Server.

Dalsze kroki