C# 如何将文件存储在数据库中?

C# 如何将文件存储在数据库中?,c#,.net,winforms,sql-server-2005,C#,.net,Winforms,Sql Server 2005,如何将用户上传的文件存储到数据库中?我想把文件存储在数据库里我们怎么做?在后端,我将sql与c#.net应用程序结合使用。一个可以降低数据库大小的解决方案是将文件的位置存储在服务器上。我需要一个文件路径 但是,如果要移动文件,则必须设置管理器。可以使用blob字段类型。从StreamReader读入文件时,将其转换为字节数组,然后将其插入blob字段 当您想要读取它时,将blob作为字节数组获取,将其读入streamreader并将其写入响应缓冲区。假设SQL 2005或更高版本,我将使用Var

如何将用户上传的文件存储到数据库中?我想把文件存储在数据库里我们怎么做?在后端,我将sql与c#.net应用程序结合使用。

一个可以降低数据库大小的解决方案是将文件的位置存储在服务器上。我需要一个文件路径


但是,如果要移动文件,则必须设置管理器。

可以使用blob字段类型。从StreamReader读入文件时,将其转换为字节数组,然后将其插入blob字段


当您想要读取它时,将blob作为字节数组获取,将其读入streamreader并将其写入响应缓冲区。

假设SQL 2005或更高版本,我将使用VarBinary(MAX)字段。将上载的文件作为字节[]传递给insert语句。据微软称,自SQL 2005以来,在数据库中存储大量数据(文件和图像)不会在很大程度上降低性能

例如:


如果您有SQL 2008,请参阅Ron Klein的建议。

MS SQL Server 2008(我想是更高版本)提供了。就为了它(或者它,随便什么:-),我想你会找到你需要的。

此解决方案适用于SQL SERVER 2005/2008

您必须使用
VARBINARY(MAX)
作为列之一创建表。在我的例子中,我创建了表
Raporty
,其中列
RaportPlik
VARBINARY(MAX)

下面有几个支持功能,您可以根据需要进行修改:

    public static void databaseFilePut(string varFilePath) {
        byte[] file;
        using (var stream = new FileStream(varFilePath, FileMode.Open, FileAccess.Read)) {
            using (var reader = new BinaryReader(stream)) {
                file = reader.ReadBytes((int) stream.Length);

            }

        }
        using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
        using (var sqlWrite = new SqlCommand("INSERT INTO Raporty (RaportPlik) Values(@File)", varConnection)) {
            sqlWrite.Parameters.Add("@File", SqlDbType.VarBinary, file.Length).Value = file;
            sqlWrite.ExecuteNonQuery();
        }
    }
    public static void databaseFileRead(string varID, string varPathToNewLocation) {
        using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
        using (var sqlQuery = new SqlCommand(@"SELECT [RaportPlik] FROM [dbo].[Raporty] WHERE [RaportID] = @varID", varConnection)) {
            sqlQuery.Parameters.AddWithValue("@varID", varID);
            using (var sqlQueryResult = sqlQuery.ExecuteReader())
                if (sqlQueryResult != null) {
                    sqlQueryResult.Read();
                    var blob = new Byte[(sqlQueryResult.GetBytes(0, 0, null, 0, int.MaxValue))];
                    sqlQueryResult.GetBytes(0, 0, blob, 0, blob.Length);
                    using (var fs = new FileStream(varPathToNewLocation, FileMode.Create, FileAccess.Write)) fs.Write(blob, 0, blob.Length);
                }
        }
    }
    public static MemoryStream databaseFileRead(string varID) {
        MemoryStream memoryStream = new MemoryStream();
        using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
        using (var sqlQuery = new SqlCommand(@"SELECT [RaportPlik] FROM [dbo].[Raporty] WHERE [RaportID] = @varID", varConnection)) {
            sqlQuery.Parameters.AddWithValue("@varID", varID);
            using (var sqlQueryResult = sqlQuery.ExecuteReader())
                if (sqlQueryResult != null) {
                    sqlQueryResult.Read();
                    var blob = new Byte[(sqlQueryResult.GetBytes(0, 0, null, 0, int.MaxValue))];
                    sqlQueryResult.GetBytes(0, 0, blob, 0, blob.Length);
                    //using (var fs = new MemoryStream(memoryStream, FileMode.Create, FileAccess.Write)) {
                    memoryStream.Write(blob, 0, blob.Length);
                    //}
                }
        }
        return memoryStream;
    }
第一种方法是将文件从驱动器放入数据库,第二种方法是获取文件并将其保存在驱动器上,第三种方法是从数据库获取文件并将其作为
MemoryStream
,这样您就可以使用它来处理其他内容,然后将其写入驱动器

第四种方法是将
MemoryStream
放入数据库:

public static int databaseFilePut(MemoryStream fileToPut) {
        int varID = 0;
        byte[] file = fileToPut.ToArray();
        const string preparedCommand = @"
                    INSERT INTO [dbo].[Raporty]
                               ([RaportPlik])
                         VALUES
                               (@File)
                        SELECT [RaportID] FROM [dbo].[Raporty]
            WHERE [RaportID] = SCOPE_IDENTITY()
                    ";
        using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
        using (var sqlWrite = new SqlCommand(preparedCommand, varConnection)) {
            sqlWrite.Parameters.Add("@File", SqlDbType.VarBinary, file.Length).Value = file;

            using (var sqlWriteQuery = sqlWrite.ExecuteReader())
                while (sqlWriteQuery != null && sqlWriteQuery.Read()) {
                    varID = sqlWriteQuery["RaportID"] is int ? (int) sqlWriteQuery["RaportID"] : 0;
                }
        }
        return varID;
    }

我仍然不推荐它,除非1)您有相当少的文件数量和较小的文件大小,或者2)您有支持解决方案扩展的基础结构。我曾在两家商店工作过,我的第一项工作是找出他们如何移动由于在数据库中存储文件而失去控制的大型数据库,特别是当那些高度冗余(由MD5校验和确定)的文件@GrayWizardx同意,但我假设哈里克里希纳已经决定将其存储在数据库中。在某些情况下(如共享主机),您无法写入文件系统。@GrayWizardx:最大为1 MB,最好将文件存储在数据库中,而不是存储在文件系统中。此外,将VARBINARY(MAX)列放在单独的表中,甚至可能是单独的文件组中,可以帮助检查情况。我想Roberts解决方案适合这种情况@Marc goodpoint@GrayWizardx:我没有-Microsoft Research有-请参阅“是否加入Blob”:sql与sql Server中的sql相同??SQL只是查询语言。。。。不是一个产品/数据库系统,真的……我们的解决方案对您有帮助吗,或者您还需要更多帮助?
public static int databaseFilePut(MemoryStream fileToPut) {
        int varID = 0;
        byte[] file = fileToPut.ToArray();
        const string preparedCommand = @"
                    INSERT INTO [dbo].[Raporty]
                               ([RaportPlik])
                         VALUES
                               (@File)
                        SELECT [RaportID] FROM [dbo].[Raporty]
            WHERE [RaportID] = SCOPE_IDENTITY()
                    ";
        using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
        using (var sqlWrite = new SqlCommand(preparedCommand, varConnection)) {
            sqlWrite.Parameters.Add("@File", SqlDbType.VarBinary, file.Length).Value = file;

            using (var sqlWriteQuery = sqlWrite.ExecuteReader())
                while (sqlWriteQuery != null && sqlWriteQuery.Read()) {
                    varID = sqlWriteQuery["RaportID"] is int ? (int) sqlWriteQuery["RaportID"] : 0;
                }
        }
        return varID;
    }