檔案寫入mysql 如何將大檔案寫入到資料庫中

2021-10-17 15:37:05 字數 3039 閱讀 1761

最近利用空閒時間自己在寫乙個檔案備份工具,因為我磁碟上的很多檔案很重要,例如很多ppt和講義。所以需要經常備份,而且因為這些檔案很多,所以需要增量備份。

我嘗試用過windows自帶的ntbackup工具,但感覺不是很爽。它不支援壓縮備份,而且介面也有點複雜。

為了響應偉大領袖的「自力更生,豐衣足食」的號召,咱決定自己寫乙個工具,專門備份到資料庫。支援壓縮,支援加密,支援增量。

本文分享一下其中一些重點的技術細節

其中乙個關鍵的技術就是將檔案使用二進位制的方式存放在資料庫的varbinary(max)的字段中。該欄位最大允許的長度為2gb。

對於一些小檔案,我們可以一次性讀取它的所有位元組,然後一次提交到資料庫

/// 這個方法演示了如何一次提交所有的位元組。這樣導致的結果是:應用程式立即需要申請等同於檔案大小的記憶體

static void submitfilebyonce() {

string file = @"f:\功夫熊貓.rmvb";//檔案大小為519mb

byte buffer = file.readallbytes(file);

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

using (sqlcommand cmd = conn.createcommand())

cmd.commandtext = "insert into files(filename,filecontents) values(@filename,@filecontents)";

cmd.parameters.addrange(

newnew sqlparameter("@filename",file),

new sqlparameter("@filecontents",buffer)

conn.open();

cmd.executenonquery();

conn.close();

但是,上面的方法有幾個問題,主要體現在如果檔案比較大的話

1. 它需要一次性很大的記憶體,具體資料等同於檔案大小。因為file.readallbytes方法是將所有位元組全部讀入到記憶體。

2. 它會導致提交失敗,就是因為資料太大了。資料庫也會拒絕。

那麼,我就對這個方法做了一下改進,將檔案拆分為5mb一段,也就是說,此時每次申請的記憶體只有5mb。這就大大地提高了可用性。

/// 這個方法是將檔案切分為5mb的塊,每次只是提交5mb,所以可能多次提交,但記憶體占用就比較小

static void submitfilestepbystep() {

string file = @"f:\功夫熊貓.rmvb";//以這個檔案為例,大小為519mb,一共需要的時間大約94秒。還是有點慢的,所以還可能需要進行壓縮

filestream fs = new filestream(file, filemode.open);

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

int readcount;

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

conn.open();

while ((readcount = fs.read(buffer, 0, buffer.length)) > 0)

using (sqlcommand cmd = conn.createcommand())

cmd.commandtext = "insert into files(filename,filecontents) values(@filename,@filecontents)";

cmd.parameters.addrange(

newnew sqlparameter("@filename",file),

new sqlparameter("@filecontents",buffer)

cmd.executenonquery();

conn.close();

這樣的話,有乙個後果就是乙個檔案,可能在資料庫中會有多條記錄。所以在讀取的時候,我們需要對其進行合併

static void downloadfile() {

string file = @"f:\功夫熊貓.rmvb";

string destfile = @"e:\temp\temp.wmv";

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

using (sqlcommand cmd = conn.createcommand())

cmd.commandtext = "select filecontents from files where filename=@filename";

cmd.parameters.addrange(

newnew sqlparameter("@filename",file),

conn.open();

sqldatareader reader = cmd.executereader();

while (reader.read())

byte buffer = (byte)reader[0];

fs.write(buffer, 0, buffer.length);

fs.close();

reader.close();

conn.close();

未能載入檔案或程式集「system.data.sqlite, version=1.0.66.0, culture=neutral, publickeytoken=db937bc2d44ff139」或它的某乙個依賴項。試圖載入格式不正確的程式。

出現這個錯誤可要小心了!

在vs「專案屬性」裡的「生成」-》目標平台設定為x86 (不要選擇x64和any cpu)再編譯後問題消失!!!!!!!!!!!

linux下如何將大檔案分為多個小檔案

1 將檔案按照儲存大小拆分 如下命令,將954m大小的檔案httpd.log,按照500mb每個檔案大小進行拆分。拆分後,變為xaa和xab兩個檔案,每個檔案大小為477m。rw r r 1 root root 477m mar 25 12 38 xab 2 將拆分後的檔案按照某個tag命名 如下命...

如何將csv檔案匯入MySQL

root debian mysqlimport uroot p123456 fields terminated by fields enclosed by fields escaped by database name var lib mysql files table name.csv引數說明 f...

Sybase IQ如何將大檔案資料迅速載入到資料庫

試想一下,如果乙個檔案5g 10g甚至更大。如何將它迅速地載入到資料庫指定的表呢?我們看看sybase iq是如何迅速地將表的資料載入到資料庫的。資料檔案格式 1440,2011 01 09 00 00 00,1,珠海,1,c網,8612345678222,221943,1,12175,1,12,1...