Сохранение и извлечение файлов из базы данных SQLite

Последнее обновление: 03.03.2021

Создание таблицы для хранения файлов

Рассмотрим, как мы можем сохранять файлы, в частности, файлы изображений в базу данных. Для этого вначале определим новую базу данных и в ней новую таблицу Files с четырьмя столбцами:

  • _id - первичный ключ и идентификатор, имеет тип INTEGER)

  • FileName будет хранить имя файла и имеет тип TEXT

  • Title будет хранить заголовок файла и также имеет тип TEXT

  • ImageData будет содержать бинарные данные файла и имеет тип BLOB

Для создания базы данных и таблицы для хранения файлов определим следующую программу:

using System;
using Microsoft.Data.Sqlite;

namespace HelloApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // выражение SQL для добавления данных
            string sqlExpression = @"CREATE TABLE Files 
                                (_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
                                 Title TEXT NOT NULL, 
                                 FileName TEXT NOT NULL,
                                 ImageData BLOB)";
            using (var connection = new SqliteConnection("Data Source=filesdata.db"))
            {
                connection.Open();

                SqliteCommand command = new SqliteCommand(sqlExpression, connection);
                command.ExecuteNonQuery();
                Console.WriteLine("Таблица Files  создана");
            }
            Console.Read();
        }
    }
}

Сохранение файлов

Определим код, в котором будут загружаться данные в таблицу:

using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Data.Sqlite;

namespace HelloApp
{
    class Program
    {
        static void Main(string[] args)
        {
			// метод в качестве параметров получает полный путь к файлу и его название
            SaveFile("D:\forest.jpg", "Лес");
            Console.Read();
        }

        private static void SaveFile(string filename, string title)
        {
            // сначала считываем файл из файловой системы
            // получаем короткое имя файла для сохранения в бд
            string shortFileName = filename.Substring(filename.LastIndexOf('\\') + 1); // forest.jpg

            // массив для хранения бинарных данных файла
            byte[] imageData;
            using (FileStream fs = new FileStream(filename, FileMode.Open))
            {
                imageData = new byte[fs.Length];
                fs.Read(imageData, 0, imageData.Length);
            }

            using (var connection = new SqliteConnection("Data Source=filesdata.db"))
            {
                connection.Open();

                SqliteCommand command = new SqliteCommand();
                command.Connection = connection;
                command.CommandText = @"INSERT INTO Files (Title, FileName, ImageData)
                                        VALUES (@FileName, @Title, @ImageData)";
                command.Parameters.Add(new SqliteParameter("@FileName", shortFileName));
                command.Parameters.Add(new SqliteParameter("@Title", title));
                command.Parameters.Add(new SqliteParameter("@ImageData", imageData));
                int number = command.ExecuteNonQuery();
                Console.WriteLine($"Добавлено объектов: {number}");
            }
        }
	}
}

В данном случае весь код сохранения файла вынесен в отдельный метод SaveFile(), который в качестве параметров получает полный путь к файлу и его название. Вначале он считывает данные с помощью класса FileStream в массив байтов. Считанный мссив байтов собственно и будет представлять данные файла.

using (FileStream fs = new FileStream(filename, FileMode.Open))
{
	imageData = new byte[fs.Length];
	fs.Read(imageData, 0, imageData.Length);
}

Затем для сохранения в бд массив байтов передается в строку запроса SQL через один из параметров:

command.Parameters.Add(new SqliteParameter("@ImageData", imageData));

Если после выполнения этой программы мы откроем базу данных через DB Browser for SQLite, то при просмотре добавленной записи мы даже можем увидеть загруженное изображение:

Сохранение изображений в базе данных SQLite в C# и .NET

Хотя в данном случае загружается изображение, но это частный случай, в принципе можно использовать и другие типы файлов.

Извлечение файлов из базы данных

Теперь произведем обратную операцию - получим файл из БД. Вначале определим класс файла, который упростит работу с данными:

public class Image
{
    public Image(int id, string filename, string title, byte[] data)
    {
        Id = id;
        FileName = filename;
        Title = title;
        Data = data;
    }
    public int Id { get; private set; }
    public string FileName { get; private set; }
    public string Title { get; private set; }
    public byte[] Data { get; private set; }
}

Теперь применим этот класс для считывания данных:

using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Data.Sqlite;

namespace HelloApp
{
    class Program
    {
        static void Main(string[] args)
        {
            GetFiles();
            Console.Read();
        }
        private static void GetFiles()
        {
            List<Image> images = new List<Image>();
            string sql = "SELECT * FROM Files";

            using (var connection = new SqliteConnection("Data Source=filesdata.db"))
            {
                connection.Open();

                SqliteCommand command = new SqliteCommand(sql, connection);
                using (SqliteDataReader reader = command.ExecuteReader())
                {
                    if (reader.HasRows) // если есть данные
                    {
                        while (reader.Read())   // построчно считываем данные
                        {
                            int id = reader.GetInt32(0);
                            string filename = reader.GetString(1);
                            string title = reader.GetString(2);
                            byte[] data = (byte[])reader.GetValue(3);

                            Image image = new Image(id, filename, title, data);
                            images.Add(image);
                        }
                    }
                    Console.WriteLine($"Считано объектов: {images.Count}");
                }

                // для примера сохраним первый файл из списка в папку приложения
                if (images.Count > 0)
                {
                    using (FileStream fs = new FileStream(images[0].FileName, FileMode.OpenOrCreate))
                    {
                        fs.Write(images[0].Data, 0, images[0].Data.Length);
                        Console.WriteLine($"Файл {images[0].Title} сохранен");
                    }
                }
            }
        }
    }
    public class Image
    {
        public Image(int id, string filename, string title, byte[] data)
        {
            Id = id;
            FileName = filename;
            Title = title;
            Data = data;
        }
        public int Id { get; private set; }
        public string FileName { get; private set; }
        public string Title { get; private set; }
        public byte[] Data { get; private set; }
    }
}

Весь код считывания вынесен в отдельный метод GetFiles(). В данном случае мы считываем все файлы из БД. Также, как и в общем случае, с помощью объекта SqliteDataReader получаем значения из БД и по ним создаем объект Image, который потом добавляется в список. Чтобы получить непосредственно данные файла, мы можем просто преобразовать соответствующее значение к массиву байт:

byte[] data = (byte[])reader.GetValue(3);

И в конце смотрим, если в списке есть элементы, то берем первый элемент и сохраняем его на локальный компьютер. И после сохранения в папке нашей программы появится загруженный из базы данных файл.

Извлечение файлов из базе данных SQLite в C# и .NET
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850