《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 通信與網(wǎng)絡(luò) > 設(shè)計(jì)應(yīng)用 > 大文件分塊上傳和下載軟件的設(shè)計(jì)與實(shí)現(xiàn)
大文件分塊上傳和下載軟件的設(shè)計(jì)與實(shí)現(xiàn)
來(lái)源:電子技術(shù)應(yīng)用2013年第8期
鄒鶴敏, 黃海于
西南交通大學(xué) 信息科學(xué)與技術(shù)學(xué)院, 四川 成都 610031
摘要: 針對(duì)大文件在網(wǎng)絡(luò)存儲(chǔ)過(guò)程中可能存在的上傳和下載失敗問(wèn)題,提出了一種利用數(shù)據(jù)庫(kù)進(jìn)行分塊存儲(chǔ)和管理較大文件的方法。將一個(gè)較大的文件分割成多塊,分別對(duì)分割后的每一塊進(jìn)行上傳或下載,從而避免了網(wǎng)絡(luò)因素對(duì)直接上傳和下載較大文件所產(chǎn)生的影響。測(cè)試表明,通過(guò)所提出的分塊與合并方法,可以有效地避免文件上傳和下載過(guò)程中可能出現(xiàn)的失敗問(wèn)題,提高了上傳和下載的效率。
中圖分類號(hào): TP392
文獻(xiàn)標(biāo)識(shí)碼: A
文章編號(hào): 0258-7998(2013)08-0137-03
Design and implementation of block upload and download large files
Zou Hemin, Huang Haiyu
School of Information Science and Technology, Southwest Jiaotong University, Chengdu 610031, China
Abstract: To solve the failure problem of the network storage process while uploading and downloading large files, this paper puts forward a method to store and manage large files in blocks by database. Split a large file into some blocks and then upload or download them separately, that can avoid the influence of the network factors on directly uploading and downloading large files. Tests show that, the method proposed in the paper can effectively avoid the failures that may exist in the file uploading and downloading process, and improve the efficiency of uploading and downloading large files.
Key words : file storage; oracle database; upload files; download files; split files into blocks; merge blcoks

    在日常生活中,人們一直都在和數(shù)據(jù)信息打交道。數(shù)據(jù)信息組織和保存的方式很多,最常用的方式就是把數(shù)據(jù)信息保存在某種文件中,然后將文件上傳到FTP服務(wù)器[1]。但是當(dāng)用戶要對(duì)文件進(jìn)行操作時(shí),查找文件會(huì)顯得比較麻煩。本文提出通過(guò)數(shù)據(jù)庫(kù)直接記錄并管理這些文件中的數(shù)據(jù)信息[2],通過(guò)數(shù)據(jù)庫(kù)的SQL語(yǔ)句對(duì)相關(guān)的記錄進(jìn)行增刪查改,操作起來(lái)非常便捷,而且在數(shù)據(jù)庫(kù)中可以采用集群的技術(shù),為用戶提供高可靠性的服務(wù)?;?a class="innerlink" href="http://ihrv.cn/tags/Oracle數(shù)據(jù)庫(kù)" title="Oracle數(shù)據(jù)庫(kù)" target="_blank">Oracle數(shù)據(jù)庫(kù)的上傳下載軟件實(shí)現(xiàn)的主要功能是將一些文件寫入到數(shù)據(jù)庫(kù),實(shí)現(xiàn)文件的上傳;然后再將數(shù)據(jù)庫(kù)中的內(nèi)容讀出,實(shí)現(xiàn)文件的下載。

    本文設(shè)計(jì)不僅實(shí)現(xiàn)了文件的上傳和下載,還針對(duì)一些較大文件的上傳提出了一種分塊上傳的思想。先指定用戶想要的文件塊的大小,這個(gè)值決定了文件要被分割的塊數(shù),較大的文件分割成若干塊,每塊都以一條記錄的形式寫到數(shù)據(jù)庫(kù)中。當(dāng)某條記錄寫數(shù)據(jù)庫(kù)失敗時(shí),只需將那些寫數(shù)據(jù)庫(kù)失敗的文件塊重新上傳,不需要將整個(gè)文件重新上傳。采用這種方式可以提高文件上傳的效率,節(jié)約重新上傳時(shí)寫數(shù)據(jù)庫(kù)的時(shí)間。但下載時(shí),如果用戶需要完整的原始文件,原來(lái)屬于同一個(gè)文件的分塊則需要重新寫到一個(gè)文件中。本文使用邊下載、邊合并的方法,實(shí)現(xiàn)了分塊文件的合并下載。用戶可以根據(jù)自己的需要,針對(duì)性地下載其中的部分文件塊。讀取一個(gè)文件分塊相比讀一個(gè)完整的大文件要快很多,文件的分塊與合并提高了文件的上傳下載效率。值得注意的是,在設(shè)置文件分塊時(shí),分塊的大小要適度,否則會(huì)影響軟件的運(yùn)行效率[3],用戶可以根據(jù)實(shí)際要求設(shè)置文件分塊的大小。
1 大文件分塊上傳和下載軟件的實(shí)現(xiàn)
1.1 文件的分塊

    將一個(gè)較大的文件上傳到數(shù)據(jù)庫(kù)時(shí),上傳速度往往會(huì)受到網(wǎng)絡(luò)寬帶的影響。針對(duì)較大文件的保存與管理,需對(duì)其進(jìn)行分塊,可以根據(jù)網(wǎng)絡(luò)的帶寬設(shè)置文件塊的大小,假設(shè)每個(gè)文件上傳的時(shí)間不超過(guò)5 s,設(shè)帶寬為k Mb/s,文件塊的大小BlockSize可以設(shè)置的范圍最好能夠滿足式(1):
     (5&times;k/8)MB<BlockSize<(5&times;10&times;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ù)庫(kù)之前,首先要在數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)存儲(chǔ)文件信息表,并定義相關(guān)的字段,方便用戶查詢和管理[4]。數(shù)據(jù)庫(kù)表中主要的相關(guān)字段包括:文件編號(hào)、文件名、文件大小、基本路徑、相對(duì)路徑、文件塊大小、文件塊編號(hào)、文件類型、文件內(nèi)容等。
    文件上傳到數(shù)據(jù)庫(kù)主要步驟為:(1)將文件的名稱、路徑、大小、類型等基本信息寫入數(shù)據(jù)庫(kù);(2)根據(jù)這些基本信息查找對(duì)應(yīng)的記錄,并將文件的內(nèi)容寫到blob字段中,文件內(nèi)容以二進(jìn)制的形式存貯在數(shù)據(jù)庫(kù)中[5-6]。
    文件分塊上傳時(shí),首先連接服務(wù)器端的數(shù)據(jù)庫(kù),在數(shù)據(jù)庫(kù)連接成功的條件下,遍歷要上傳的文件所在的路徑。當(dāng)查找到要上傳的文件時(shí),根據(jù)文件分塊的大小,計(jì)算文件分割的塊數(shù)和最后一個(gè)文件塊的大小,從第一個(gè)文件塊開(kāi)始,計(jì)算過(guò)程如下:
    (1) 判斷是否成功連接到數(shù)據(jù)庫(kù)。
    (2) 判斷這是否為最后一個(gè)文件塊,如果是,則從文件中讀取最后一個(gè)文件塊,寫入數(shù)據(jù)庫(kù)后結(jié)束;否則從文件中讀取BlockSize個(gè)字節(jié)。
    (3) 用Insert命令在對(duì)應(yīng)的表中寫入文件的編號(hào)、文件名稱、文件大小、文件的基本路徑及相對(duì)路徑、文件類型、文件塊的大小和編號(hào)。
    (4) 通過(guò)文件編號(hào)、文件路徑,文件名稱和文件塊編號(hào)查找相應(yīng)的記錄。
    (5) 將要寫入數(shù)據(jù)庫(kù)的文件內(nèi)容保存在一個(gè)安全數(shù)組中,并調(diào)用AppendChunk()函數(shù)將該塊文件內(nèi)容填到對(duì)應(yīng)的blob字段當(dāng)中,并更新記錄。
    (6)為寫入記錄中的文件的路徑、文件名以及文件塊編號(hào)設(shè)置標(biāo)記,方便重新上傳時(shí)定位斷點(diǎn)的位置,跳轉(zhuǎn)到步驟(1)。
    文件分塊上傳的流程圖如圖1所示。

    如果服務(wù)器數(shù)據(jù)庫(kù)與客戶端的連接斷開(kāi),將導(dǎo)致文件上傳失敗。在客戶端與服務(wù)器端數(shù)據(jù)庫(kù)重新建立連接后,需要續(xù)傳文件,同時(shí)要通過(guò)斷開(kāi)數(shù)據(jù)庫(kù)時(shí)的標(biāo)記,找到上次上傳文件的斷點(diǎn)。
    續(xù)傳文件時(shí),為了找到文件續(xù)傳的起始位置,依然要遍歷文件所在的路徑,通過(guò)文件路徑和名稱找到對(duì)應(yīng)的文件,再使用文件塊的編號(hào)和文件塊的大小獲取下一次文件要上傳的位置。設(shè)offset為文件指針的偏移值,BlockNo為文件塊的編號(hào),BlockSize為文件塊的大小,三者之間的關(guān)系如下:
    offset=BlockNo&times;BlockSize  (4)
式中,被標(biāo)記文件塊的編號(hào)BlockNo乘以文件塊的大小BlockSize,就是續(xù)傳時(shí)讀取文件的偏移值。通過(guò)這個(gè)方法,就可以找到斷點(diǎn)所在的文件塊位置,實(shí)現(xiàn)文件的續(xù)傳, 從而避免重新上傳之前已經(jīng)寫入數(shù)據(jù)庫(kù)的文件塊。
1.3 分塊文件的下載
    因?yàn)槲募潜4嬖跀?shù)據(jù)庫(kù)中的,用戶可用通過(guò)SQL命令對(duì)數(shù)據(jù)庫(kù)中的記錄進(jìn)行增刪查改等操作,這比存儲(chǔ)在FTP服務(wù)器中的文件處理要方便很多。下載的過(guò)程其實(shí)就是上傳的逆過(guò)程,思想相似。
    下載時(shí)根據(jù)相關(guān)的查詢條件,如果存在符合條件的記錄,即可對(duì)這些記錄保存的文件進(jìn)行下載,在成功連接到數(shù)據(jù)庫(kù)的條件下,從第一條記錄開(kāi)始執(zhí)行以下過(guò)程:
    (1)判斷是否成功連接到數(shù)據(jù)庫(kù)。
    (2)判斷該記錄是否超過(guò)最后一條記錄編號(hào),如果是,下載結(jié)束;否則跳轉(zhuǎn)到步驟(3)。
    (3)從記錄中獲取文件的類型、文件名以及相對(duì)路徑,判斷該文件是否已經(jīng)存在,如果不存在,則根據(jù)文件的類型創(chuàng)建一個(gè)文件,以可追加的形式打開(kāi)文件。
    (4)調(diào)用GetChunk()函數(shù)獲取blob字段中的內(nèi)容,并保存在一個(gè)安全數(shù)組中,最后將安全數(shù)組中的數(shù)據(jù)寫入文件。
    (5)關(guān)閉文件,并標(biāo)記該記錄中的文件路徑、文件名以及文件塊編號(hào),并跳轉(zhuǎn)到步驟(1)。
1.4 分塊文件的合并
    本文雖然實(shí)現(xiàn)了文件的分塊下載,但是在實(shí)際情況中,人們通常希望使用完整的文件,而不是一個(gè)文件塊,所以在下載的過(guò)程中需要將各個(gè)文件的分塊重新合并成一個(gè)文件。本文采用的方法是在下載的過(guò)程中即可進(jìn)行合并操作,文件合并下載的流程圖如圖2所示。

 

 

    文件的合并是文件合并下載過(guò)程中的一部分,即每次下載某條記錄中的文件內(nèi)容時(shí),先判斷該文件塊將寫入的文件。
    用戶根據(jù)文件名稱,文件路徑等信息查找所需要的文件,如果存在符合條件的記錄,就依次訪問(wèn)這些記錄,并將每條記錄中的文件內(nèi)容讀取出來(lái),寫入相應(yīng)的文件中。從查詢到的第一條記錄開(kāi)始:
    (1)判斷是否已經(jīng)訪問(wèn)了最后一條符合條件的記錄,如果是,則結(jié)束,否則轉(zhuǎn)到步驟(2)。
    (2)獲取文件的路徑、文件名稱、文件類型等基本信息,    判斷當(dāng)前路徑下是否已經(jīng)存在這樣的文件,如果不存在,將創(chuàng)建一個(gè)對(duì)應(yīng)的文件;否則跳轉(zhuǎn)到步驟(3)。
    (3)將記錄中的文件相對(duì)路徑、文件名兩個(gè)字段的內(nèi)容與上一條記錄中的相對(duì)路徑和文件名匹配,如果相同,則將文件內(nèi)容追加到該文件;否則根據(jù)該文件塊的基本信息重新創(chuàng)建一個(gè)文件。
    (4)標(biāo)記該條記錄并移到下一條記錄,并跳轉(zhuǎn)到步驟(1)。
    所有記錄被訪問(wèn)完的同時(shí),所有的文件分塊都被寫入了相應(yīng)文件中,既不會(huì)出現(xiàn)文件內(nèi)容的覆蓋問(wèn)題,也不會(huì)額外地占用存儲(chǔ)空間。
2 實(shí)驗(yàn)分析
      通過(guò)測(cè)試發(fā)現(xiàn),文件的完整上傳所消耗的時(shí)間最短,但是上傳失敗后要重新上傳整個(gè)文件。如果使用文件的分塊上傳,文件分塊的大小要適當(dāng),分塊越多,上傳的速度就越慢。因?yàn)橛涗浢總€(gè)分塊文件的基本信息也要消耗一定的時(shí)間,在上傳失敗需要重新上傳的情況下,只需上傳剩下的沒(méi)有上傳成功的文件,效率有所提高。在下載的過(guò)程中,單塊文件明顯比整個(gè)文件的下載要快,因?yàn)閱螇K文件下載只需要讀取塊數(shù)據(jù)。而文件的合并下載時(shí)間比整塊文件下載時(shí)間要長(zhǎng),因?yàn)樵诤喜⒌倪^(guò)程中要判斷各個(gè)文件塊是否來(lái)源于同一個(gè)原始文件,會(huì)消耗一定的時(shí)間。
    相對(duì)于普通的將文件上傳到FTP服務(wù)器,本文實(shí)現(xiàn)了基于Oracle數(shù)據(jù)庫(kù)的大文件分塊上傳下載應(yīng)用軟件,將文件的內(nèi)容以二進(jìn)制的形式分散保存在Oracle數(shù)據(jù)庫(kù)中,這不僅可以對(duì)大量數(shù)據(jù)信息進(jìn)行管理,還可以使得不同的用戶共享很多數(shù)據(jù)信息。文件的分塊上傳采用文件分割技術(shù),將文件分塊保存在數(shù)據(jù)庫(kù)中。通過(guò)文件的續(xù)傳,避免了由于各種網(wǎng)絡(luò)原因?qū)е碌膶憯?shù)據(jù)庫(kù)操作失敗,需要將整個(gè)文件重新上傳的問(wèn)題。文件的合并下載解決了同一個(gè)文件中不同分塊的合并問(wèn)題,避免了先下載文件再進(jìn)行合并的做法,提高了軟件的運(yùn)行效率。
參考文獻(xiàn)
[1] 馮素梅.基于FTP的文件上傳與下載研究[J].北京電力高等??茖W(xué)校學(xué)報(bào)(自然科學(xué)版),2010,27(5):197-199.
[2] 陶宏才.數(shù)據(jù)庫(kù)原理及設(shè)計(jì)[M]. 北京:清華大學(xué)出版社,2007.
[3] 張翼.BLOB數(shù)據(jù)優(yōu)化算法及其應(yīng)用[J].計(jì)算機(jī)測(cè)量與控制,2011(6):1478-1480.
[4] 徐孝凱,賀桂英.數(shù)據(jù)庫(kù)基礎(chǔ)與SQL Server應(yīng)用開(kāi)發(fā)[M].北京:清華大學(xué)出版社,2008.
[5] 謝華成,張昆朋,范黎林,等.基于文件分割的二進(jìn)制大對(duì)象存取算法[J].計(jì)算機(jī)應(yīng)用,2011,31(10):2612-2616.
[6] 趙宇峰,張燁.VC存取數(shù)據(jù)庫(kù)的BLOB類型的方法[J].微型電腦應(yīng)用,2007,23(3):59-60.

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。