如何将大文件写入到数据库中

如何将大文件写入到数据库中,第1张

最近利用空闲时间自己在写一个文件备份工具,因为我磁盘上的很多文件很重要,例如很多PPT和讲义。所以需要经常备份,而且因为这些文件很多,所以需要增量备份。

我尝试用过windows自带的ntbackup工具,但感觉不是很爽。它不支持压缩备份,而且界面也有点复杂。

为了响应伟大领袖的“自力更生,丰衣足食”的号召,咱决定自己写一个工具,专门备份到数据。支持压缩,支持加密,支持增量。

本文分享一下其中一些重点的技术细节

其中一个关键的技术就是将文件使用二进制的方式存放在数据库的varbinary(max)的字段中。该字段最大允许的长度为2GB。

对于一些小文件,我们可以一次性读取它的所有字节,然后一次提交到数据库

/// <summary>

/// 这个方法演示了如何一次提交所有的字节。这样导致的结果是:应用程序立即需要申请等同于文件大小的内存

/// </summary>

static void SubmitFileByOnce() {

string file = @"F:\功夫熊猫rmvb";//文件大小为519MB

byte[] buffer = FileReadAllBytes(file);

using (SqlConnection conn = new SqlConnection("server=(local);database=demo;integrated security=true")) {

using (SqlCommand cmd = connCreateCommand())

{

cmdCommandText = "INSERT INTO Files(FileName,FileContents) VALUES(@fileName,@fileContents)";

cmdParametersAddRange(

new[]

{

new SqlParameter("@fileName",file),

new SqlParameter("@fileContents",buffer)

});

connOpen();

cmdExecuteNonQuery();

connClose();

}

}

}

但是,上面的方法有几个问题,主要体现在如果文件比较大的话

1 它需要一次性很大的内存,具体数据等同于文件大小。因为FileReadAllBytes方法是将所有字节全部读入到内存。

2 它会导致提交失败,就是因为数据太大了。数据库也会拒绝。

那么,我就对这个方法做了一下改进,将文件拆分为5MB一段,也就是说,此时每次申请的内存只有5MB。这就大大地提高了可用性。

/// <summary>

/// 这个方法是将文件切分为5MB的块,每次只是提交5MB,所以可能多次提交,但内存占用就比较小

/// </summary>

static void SubmitFileStepByStep() {

string file = @"F:\功夫熊猫rmvb";//以这个文件为例,大小为519MB,一共需要的时间大约94秒。还是有点慢的,所以还可能需要进行压缩

FileStream fs = new FileStream(file, FileModeOpen);

byte[] buffer = new byte[5 1024 1024];

int readCount;

using (SqlConnection conn = new SqlConnection("server=(local);database=demo;integrated security=true"))

{

connOpen();

while ((readCount = fsRead(buffer, 0, bufferLength)) > 0)

{

using (SqlCommand cmd = connCreateCommand())

{

cmdCommandText = "INSERT INTO Files(FileName,FileContents) VALUES(@fileName,@fileContents)";

cmdParametersAddRange(

new[]

{

new SqlParameter("@fileName",file),

new SqlParameter("@fileContents",buffer)

});

cmdExecuteNonQuery();

}

}

connClose();

}

}

这样的话,有一个后果就是一个文件,可能在数据库中会有多条记录。所以在读取的时候,我们需要对其进行合并

static void DownloadFile() {

string file = @"F:\功夫熊猫rmvb";

string destfile = @"E:\Temp\Tempwmv";

using (SqlConnection conn = new SqlConnection("server=(local);database=demo;integrated security=true"))

{

using (SqlCommand cmd = connCreateCommand())

{

cmdCommandText = "SELECT FileContents FROM Files WHERE FileName=@fileName";

cmdParametersAddRange(

new[]

{

new SqlParameter("@fileName",file),

});

connOpen();

SqlDataReader reader = cmdExecuteReader();

FileStream fs = new FileStream(destfile, FileModeAppend, FileAccessWrite);

while (readerRead())

{

byte[] buffer = (byte[])reader[0];

fsWrite(buffer, 0, bufferLength);

}

fsClose();

readerClose();

connClose();

}

}

}

本文由作者:陈希章

1、数据库是由主要文件、次要文件、事务日志文件所组成的。数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,数据管理不再仅仅是存储和管理数据。

2、在信息化社会,充分有效地管理和利用各类信息资源,是进行科学研究和决策管理的前提条件。数据库技术是管理信息系统、办公自动化系统、决策支持系统等各类信息系统的核心部分,是进行科学研究和决策管理的重要技术手段。

附加数据库

或者导入数据库

sql本身有数据导入的 *** 作。但如果要从一个备份的文件中导入数据,则要进行另外的 *** 作。下面以一个例子进行说明。

sql服务器上已有一个doe数据库,并且里面有大量的数据,现准备从另外一个备份文件a1bak(不是doe数据库的备份文件)中导入另外的数据(即导入后在doe中增加一些数据表,表中已录有数据),并保持原doe的数据不变。

1、首先,在“sql企业管理器”中新建一个临时数据库a1。

2、右击a1数据库,选择:所有任务->还原数据库。

3、在“还原数据库”窗口中,选择:“从设备”。

4、点击“选择设备”。

5、点击“添加”。

6、从文件名中选择要还原的数据库文件,如a1bak。

7、点击“确定”,返回“还原数据库”窗口。

8、点击“选项”卡,进入选项设置。

9、钩选:“在现有数据库上强制还原”。

10、修改“移到物理文件名”为:“c:\a1ldf”、“c:\a1mdf”。

11、点确定,即可导入备份文件中的数据到临时数据库a1中。

12、此时,你可以将数据从a1导入到另外一真正要导入的数据库中,如doe数据库。

(下面的数据导入 *** 作为sql2000企业管理器的一般数据导入导出 *** 作。)

13、在“sql企业管理器”中选择“doe”数据库。

14、右击doe数据库,选择:所有任务->导入数据。

15、在“dts导入/导出向导”窗口的“选择数据源”中,数据源选择刚才建立并导入数据的临时数据库a1。点击下一步。

16、在“选择目的”中,系统已经默认为doe数据库。

17、连续点击“下一步”,直到完成。

经过上面的 *** 作,你已经成功地将备份文件a1bak中数据导入doe数据库中,并且doe数据库原有数据不变。

此时,你可以删除临时数据库a1。

以上就是关于如何将大文件写入到数据库中全部的内容,包括:如何将大文件写入到数据库中、请问数据库是由什么文件组成的、mysql怎么导入和导出数据库文件等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9356525.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存