文獻(xiàn)標(biāo)識碼: A
文章編號: 0258-7998(2013)08-0137-03
在日常生活中,人們一直都在和數(shù)據(jù)信息打交道,。數(shù)據(jù)信息組織和保存的方式很多,最常用的方式就是把數(shù)據(jù)信息保存在某種文件中,,然后將文件上傳到FTP服務(wù)器[1],。但是當(dāng)用戶要對文件進(jìn)行操作時(shí),查找文件會(huì)顯得比較麻煩,。本文提出通過數(shù)據(jù)庫直接記錄并管理這些文件中的數(shù)據(jù)信息[2],通過數(shù)據(jù)庫的SQL語句對相關(guān)的記錄進(jìn)行增刪查改,操作起來非常便捷,,而且在數(shù)據(jù)庫中可以采用集群的技術(shù),,為用戶提供高可靠性的服務(wù)?;?a class="innerlink" href="http://wldgj.com/tags/Oracle數(shù)據(jù)庫" title="Oracle數(shù)據(jù)庫" target="_blank">Oracle數(shù)據(jù)庫的上傳下載軟件實(shí)現(xiàn)的主要功能是將一些文件寫入到數(shù)據(jù)庫,,實(shí)現(xiàn)文件的上傳;然后再將數(shù)據(jù)庫中的內(nèi)容讀出,,實(shí)現(xiàn)文件的下載,。
本文設(shè)計(jì)不僅實(shí)現(xiàn)了文件的上傳和下載,,還針對一些較大文件的上傳提出了一種分塊上傳的思想。先指定用戶想要的文件塊的大小,,這個(gè)值決定了文件要被分割的塊數(shù),,較大的文件分割成若干塊,每塊都以一條記錄的形式寫到數(shù)據(jù)庫中,。當(dāng)某條記錄寫數(shù)據(jù)庫失敗時(shí),,只需將那些寫數(shù)據(jù)庫失敗的文件塊重新上傳,不需要將整個(gè)文件重新上傳,。采用這種方式可以提高文件上傳的效率,,節(jié)約重新上傳時(shí)寫數(shù)據(jù)庫的時(shí)間。但下載時(shí),,如果用戶需要完整的原始文件,,原來屬于同一個(gè)文件的分塊則需要重新寫到一個(gè)文件中。本文使用邊下載,、邊合并的方法,,實(shí)現(xiàn)了分塊文件的合并下載。用戶可以根據(jù)自己的需要,,針對性地下載其中的部分文件塊,。讀取一個(gè)文件分塊相比讀一個(gè)完整的大文件要快很多,文件的分塊與合并提高了文件的上傳下載效率,。值得注意的是,,在設(shè)置文件分塊時(shí),分塊的大小要適度,,否則會(huì)影響軟件的運(yùn)行效率[3],,用戶可以根據(jù)實(shí)際要求設(shè)置文件分塊的大小。
1 大文件分塊上傳和下載軟件的實(shí)現(xiàn)
1.1 文件的分塊
將一個(gè)較大的文件上傳到數(shù)據(jù)庫時(shí),,上傳速度往往會(huì)受到網(wǎng)絡(luò)寬帶的影響,。針對較大文件的保存與管理,需對其進(jìn)行分塊,,可以根據(jù)網(wǎng)絡(luò)的帶寬設(shè)置文件塊的大小,,假設(shè)每個(gè)文件上傳的時(shí)間不超過5 s,設(shè)帶寬為k Mb/s,文件塊的大小BlockSize可以設(shè)置的范圍最好能夠滿足式(1):
(5×k/8)MB<BlockSize<(5×10×k/8)MB (1)
若文件塊的大小用BlockSize表示,則文件分成的塊數(shù)nCount與文件的大小之間的關(guān)系為:
nCount=Flength/BlockSize+1 (2)
K=Flength%BlockSize (3)
其中Flength代表原始文件的大小,,K代表最后一個(gè)文件分塊的大小,。因?yàn)槲募拇笮∨c文件塊的大小不一定剛好是整除的關(guān)系。最特殊的情況就是某文件的大小剛好小于文件塊的大小,,此時(shí)的文件就只有一塊,,即該文件本身。
1.2 分塊文件的上傳
將分塊文件上傳到數(shù)據(jù)庫之前,,首先要在數(shù)據(jù)庫中創(chuàng)建一個(gè)存儲(chǔ)文件信息表,,并定義相關(guān)的字段,,方便用戶查詢和管理[4]。數(shù)據(jù)庫表中主要的相關(guān)字段包括:文件編號,、文件名,、文件大小、基本路徑,、相對路徑,、文件塊大小、文件塊編號,、文件類型,、文件內(nèi)容等。
文件上傳到數(shù)據(jù)庫主要步驟為:(1)將文件的名稱,、路徑,、大小、類型等基本信息寫入數(shù)據(jù)庫;(2)根據(jù)這些基本信息查找對應(yīng)的記錄,,并將文件的內(nèi)容寫到blob字段中,,文件內(nèi)容以二進(jìn)制的形式存貯在數(shù)據(jù)庫中[5-6]。
文件分塊上傳時(shí),首先連接服務(wù)器端的數(shù)據(jù)庫,,在數(shù)據(jù)庫連接成功的條件下,遍歷要上傳的文件所在的路徑,。當(dāng)查找到要上傳的文件時(shí),根據(jù)文件分塊的大小,,計(jì)算文件分割的塊數(shù)和最后一個(gè)文件塊的大小,,從第一個(gè)文件塊開始,計(jì)算過程如下:
(1) 判斷是否成功連接到數(shù)據(jù)庫,。
(2) 判斷這是否為最后一個(gè)文件塊,,如果是,則從文件中讀取最后一個(gè)文件塊,,寫入數(shù)據(jù)庫后結(jié)束,;否則從文件中讀取BlockSize個(gè)字節(jié)。
(3) 用Insert命令在對應(yīng)的表中寫入文件的編號,、文件名稱,、文件大小、文件的基本路徑及相對路徑,、文件類型,、文件塊的大小和編號。
(4) 通過文件編號,、文件路徑,文件名稱和文件塊編號查找相應(yīng)的記錄,。
(5) 將要寫入數(shù)據(jù)庫的文件內(nèi)容保存在一個(gè)安全數(shù)組中,,并調(diào)用AppendChunk()函數(shù)將該塊文件內(nèi)容填到對應(yīng)的blob字段當(dāng)中,,并更新記錄。
(6)為寫入記錄中的文件的路徑,、文件名以及文件塊編號設(shè)置標(biāo)記,,方便重新上傳時(shí)定位斷點(diǎn)的位置,跳轉(zhuǎn)到步驟(1),。
文件分塊上傳的流程圖如圖1所示,。
如果服務(wù)器數(shù)據(jù)庫與客戶端的連接斷開,將導(dǎo)致文件上傳失敗,。在客戶端與服務(wù)器端數(shù)據(jù)庫重新建立連接后,,需要續(xù)傳文件,同時(shí)要通過斷開數(shù)據(jù)庫時(shí)的標(biāo)記,找到上次上傳文件的斷點(diǎn),。
續(xù)傳文件時(shí),,為了找到文件續(xù)傳的起始位置,依然要遍歷文件所在的路徑,,通過文件路徑和名稱找到對應(yīng)的文件,,再使用文件塊的編號和文件塊的大小獲取下一次文件要上傳的位置。設(shè)offset為文件指針的偏移值,,BlockNo為文件塊的編號,,BlockSize為文件塊的大小,三者之間的關(guān)系如下:
offset=BlockNo×BlockSize (4)
式中,,被標(biāo)記文件塊的編號BlockNo乘以文件塊的大小BlockSize,,就是續(xù)傳時(shí)讀取文件的偏移值。通過這個(gè)方法,,就可以找到斷點(diǎn)所在的文件塊位置,,實(shí)現(xiàn)文件的續(xù)傳, 從而避免重新上傳之前已經(jīng)寫入數(shù)據(jù)庫的文件塊,。
1.3 分塊文件的下載
因?yàn)槲募潜4嬖跀?shù)據(jù)庫中的,,用戶可用通過SQL命令對數(shù)據(jù)庫中的記錄進(jìn)行增刪查改等操作,這比存儲(chǔ)在FTP服務(wù)器中的文件處理要方便很多,。下載的過程其實(shí)就是上傳的逆過程,,思想相似。
下載時(shí)根據(jù)相關(guān)的查詢條件,,如果存在符合條件的記錄,,即可對這些記錄保存的文件進(jìn)行下載,在成功連接到數(shù)據(jù)庫的條件下,從第一條記錄開始執(zhí)行以下過程:
(1)判斷是否成功連接到數(shù)據(jù)庫,。
(2)判斷該記錄是否超過最后一條記錄編號,,如果是,下載結(jié)束,;否則跳轉(zhuǎn)到步驟(3),。
(3)從記錄中獲取文件的類型,、文件名以及相對路徑,判斷該文件是否已經(jīng)存在,,如果不存在,,則根據(jù)文件的類型創(chuàng)建一個(gè)文件,以可追加的形式打開文件,。
(4)調(diào)用GetChunk()函數(shù)獲取blob字段中的內(nèi)容,,并保存在一個(gè)安全數(shù)組中,最后將安全數(shù)組中的數(shù)據(jù)寫入文件,。
(5)關(guān)閉文件,,并標(biāo)記該記錄中的文件路徑、文件名以及文件塊編號,,并跳轉(zhuǎn)到步驟(1),。
1.4 分塊文件的合并
本文雖然實(shí)現(xiàn)了文件的分塊下載,但是在實(shí)際情況中,,人們通常希望使用完整的文件,,而不是一個(gè)文件塊,所以在下載的過程中需要將各個(gè)文件的分塊重新合并成一個(gè)文件,。本文采用的方法是在下載的過程中即可進(jìn)行合并操作,文件合并下載的流程圖如圖2所示,。
文件的合并是文件合并下載過程中的一部分,即每次下載某條記錄中的文件內(nèi)容時(shí),,先判斷該文件塊將寫入的文件,。
用戶根據(jù)文件名稱,文件路徑等信息查找所需要的文件,,如果存在符合條件的記錄,,就依次訪問這些記錄,并將每條記錄中的文件內(nèi)容讀取出來,,寫入相應(yīng)的文件中,。從查詢到的第一條記錄開始:
(1)判斷是否已經(jīng)訪問了最后一條符合條件的記錄,如果是,,則結(jié)束,,否則轉(zhuǎn)到步驟(2)。
(2)獲取文件的路徑,、文件名稱,、文件類型等基本信息, 判斷當(dāng)前路徑下是否已經(jīng)存在這樣的文件,,如果不存在,,將創(chuàng)建一個(gè)對應(yīng)的文件;否則跳轉(zhuǎn)到步驟(3)。
(3)將記錄中的文件相對路徑,、文件名兩個(gè)字段的內(nèi)容與上一條記錄中的相對路徑和文件名匹配,如果相同,,則將文件內(nèi)容追加到該文件;否則根據(jù)該文件塊的基本信息重新創(chuàng)建一個(gè)文件,。
(4)標(biāo)記該條記錄并移到下一條記錄,并跳轉(zhuǎn)到步驟(1)。
所有記錄被訪問完的同時(shí),,所有的文件分塊都被寫入了相應(yīng)文件中,既不會(huì)出現(xiàn)文件內(nèi)容的覆蓋問題,,也不會(huì)額外地占用存儲(chǔ)空間。
2 實(shí)驗(yàn)分析
通過測試發(fā)現(xiàn),文件的完整上傳所消耗的時(shí)間最短,,但是上傳失敗后要重新上傳整個(gè)文件,。如果使用文件的分塊上傳,文件分塊的大小要適當(dāng),,分塊越多,,上傳的速度就越慢。因?yàn)橛涗浢總€(gè)分塊文件的基本信息也要消耗一定的時(shí)間,,在上傳失敗需要重新上傳的情況下,,只需上傳剩下的沒有上傳成功的文件,效率有所提高,。在下載的過程中,,單塊文件明顯比整個(gè)文件的下載要快,因?yàn)閱螇K文件下載只需要讀取塊數(shù)據(jù),。而文件的合并下載時(shí)間比整塊文件下載時(shí)間要長,,因?yàn)樵诤喜⒌倪^程中要判斷各個(gè)文件塊是否來源于同一個(gè)原始文件,會(huì)消耗一定的時(shí)間,。
相對于普通的將文件上傳到FTP服務(wù)器,,本文實(shí)現(xiàn)了基于Oracle數(shù)據(jù)庫的大文件分塊上傳下載應(yīng)用軟件,將文件的內(nèi)容以二進(jìn)制的形式分散保存在Oracle數(shù)據(jù)庫中,,這不僅可以對大量數(shù)據(jù)信息進(jìn)行管理,,還可以使得不同的用戶共享很多數(shù)據(jù)信息。文件的分塊上傳采用文件分割技術(shù),,將文件分塊保存在數(shù)據(jù)庫中,。通過文件的續(xù)傳,避免了由于各種網(wǎng)絡(luò)原因?qū)е碌膶憯?shù)據(jù)庫操作失敗,,需要將整個(gè)文件重新上傳的問題,。文件的合并下載解決了同一個(gè)文件中不同分塊的合并問題,避免了先下載文件再進(jìn)行合并的做法,,提高了軟件的運(yùn)行效率,。
參考文獻(xiàn)
[1] 馮素梅.基于FTP的文件上傳與下載研究[J].北京電力高等專科學(xué)校學(xué)報(bào)(自然科學(xué)版),2010,27(5):197-199.
[2] 陶宏才.數(shù)據(jù)庫原理及設(shè)計(jì)[M]. 北京:清華大學(xué)出版社,2007.
[3] 張翼.BLOB數(shù)據(jù)優(yōu)化算法及其應(yīng)用[J].計(jì)算機(jī)測量與控制,2011(6):1478-1480.
[4] 徐孝凱,賀桂英.數(shù)據(jù)庫基礎(chǔ)與SQL Server應(yīng)用開發(fā)[M].北京:清華大學(xué)出版社,2008.
[5] 謝華成,張昆朋,范黎林,等.基于文件分割的二進(jìn)制大對象存取算法[J].計(jì)算機(jī)應(yīng)用,2011,31(10):2612-2616.
[6] 趙宇峰,張燁.VC存取數(shù)據(jù)庫的BLOB類型的方法[J].微型電腦應(yīng)用,2007,23(3):59-60.