朱亞林 紀(jì)宏偉
摘 要:大數(shù)據(jù)時代,信息的分享與傳播越來越受到重視。人們更加專注于提高信息的分享效率、提升信息的傳播速度。在日常工作中,組建一個開放的自主式、智能式、有著較強(qiáng)安全性能的文件共享系統(tǒng),可以大幅提高工作效率,節(jié)約工作成本。本文將借助于Python語言,采用分布式程序設(shè)計理念搭建一個文件共享的網(wǎng)絡(luò)平臺,這即是對傳統(tǒng)文件共享形式的一種補(bǔ)充,也是一次創(chuàng)新與嘗試。
關(guān)鍵詞:Python;分布式;文件共享系統(tǒng);自主;智能
中圖分類號:TP393.0 文獻(xiàn)標(biāo)識碼:A 文章編號:2095-2163(2015)04-
Implementation of A Distributed File Sharing System based on Python
ZHU Yalin, JI Hongwei
(Nantong Normal College, Rugao Jiangsu 226500,China)
Abstract: In the era of big data,information sharing and communication is getting more and more attention.People are more focused on improving the efficiency of information sharing and improving the speed of information transmission. In daily work, an open autonomous, intelligent file sharing system with the strong performance of safety, can greatly improve the work efficiency, and save the cost of work. This article will use the Python language, adopting the distributed application design concept to build a file sharing network platform, which is not only a supplement to the traditional form of file sharing, but also is an innovation and try.
Keywords :Python; Distributed; File Sharing System; Autonomous; Intelligent
0 引 言
大數(shù)據(jù)時代,信息的傳播與分享是創(chuàng)造效率的必要條件,也是人與人之間交流與協(xié)作的不可或缺的最佳途徑。在此環(huán)境之下,每條信息及其背后的各種介質(zhì),其實都是大數(shù)據(jù)的重要組成部分,如果能將這些對象科學(xué)合理地納入到數(shù)據(jù)環(huán)境中來,會得到意想不到的效果。因此,無論在日常生活還是研究工作中,人們都必須學(xué)會運用大數(shù)據(jù)的思維來探討解決問題。
在工作中,各類文檔的傳遞交換是常規(guī)普通的頻發(fā)現(xiàn)象。一般的處理方式不外乎以下幾種:借助于單位的OA系統(tǒng)和QQ等即時通工具進(jìn)行傳輸、通過Email進(jìn)行收發(fā)、通過云空間進(jìn)行分享、建立FTP站點進(jìn)行共享、利用U盤拷貝分享等等[ ]。以上的傳輸手段,類型多樣,也各有利弊,此處暫且不對其各自所有的特性進(jìn)行分析評價。本文研究實現(xiàn)的基于Python語言的一種分布式文件共享系統(tǒng),則是可以作為上述各種共享方式的補(bǔ)充。可以說,該系統(tǒng)融入了大數(shù)據(jù)背景下數(shù)據(jù)處理的理念,將一個團(tuán)體內(nèi)部的所有成員,都看作是數(shù)據(jù)的發(fā)布者與獲得者,即如同搭積木一樣地將其各自所擁有的數(shù)據(jù)加入到共享環(huán)境中來,而要想獲得這些數(shù)據(jù),則只需一個關(guān)鍵字搜索即可實現(xiàn)。
1分布式文件共享系統(tǒng)的設(shè)計思路
所謂分布式文件共享是指,所有可檢索的共享文件不存在于固定的服務(wù)器上,而是分布于加入該文件共享環(huán)境中的各臺獨立的計算機(jī)上[ ][ ],該環(huán)境中的用戶既是數(shù)據(jù)的提供者,也是數(shù)據(jù)的獲取者。
整個系統(tǒng)的設(shè)計思路如下:首先,該環(huán)境中的用戶會根據(jù)實際情況設(shè)置一個用于共享的文件夾,系統(tǒng)會自動提交共享目錄結(jié)構(gòu),并將該目錄進(jìn)行共享;其次,用戶可以依托一個通用的搜索入口,在布設(shè)于該環(huán)境范圍內(nèi)的所有計算機(jī)的共享目錄中進(jìn)行檢索,并下載所需要的文件。為方便說明,下文將所有加入分布式文件共享系統(tǒng)的獨立計算機(jī)稱之為客戶機(jī),而負(fù)責(zé)承擔(dān)搜索任務(wù)的計算機(jī)稱為服務(wù)器。
1.1 客戶機(jī)配置
要加入該分布式文件共享系統(tǒng),則需要在客戶機(jī)上安裝客戶端軟件,該軟件主要負(fù)責(zé)如下方面功能的實現(xiàn):
(1) 獲取共享目錄結(jié)構(gòu)
允許用戶設(shè)置本臺電腦上用于共享的文件夾,客戶端會自動掃描共享文件夾的目錄結(jié)構(gòu),并將其進(jìn)一步反饋給服務(wù)器,以利于共享情況的實時更新。
(2) 實現(xiàn)文件及文件夾的共享
客戶端還有一大功能即是將共享文件或文件夾以HTTP協(xié)議的形式共享和展示,以方便其他用戶瀏覽、下載。之所以選擇HTTP服務(wù),是因為實現(xiàn)協(xié)議的服務(wù)平臺搭建簡單,運行環(huán)境跨平臺,且無需下載軟件支持,而只需配有瀏覽器即可完成。
1.2 服務(wù)器配置
系統(tǒng)的服務(wù)器端,其主要功能是用于收集各個客戶端發(fā)來的目錄索引,并將其保存到統(tǒng)一文件夾下,同時為用戶提供一個搜索的接口用于文件檢索,當(dāng)用戶輸入關(guān)鍵字時,則在各個成員提供的共享目錄索引中進(jìn)行檢索,并給出反饋結(jié)果,進(jìn)而引導(dǎo)用戶到指定地址下載文件。
綜上所述不難發(fā)現(xiàn),該系統(tǒng)的優(yōu)勢在于:在某一局域網(wǎng)內(nèi)部,再也不必配備專門的服務(wù)器來存儲規(guī)模龐大的共享數(shù)據(jù)了,成員與成員之間可以根據(jù)實際需要,將自己計算機(jī)上的公用文件處于共享狀態(tài),方便他人獲??;而且用戶自身則可以保留原版文件,同時擁有對所屬文件的更新權(quán),使其無論何時均處于最新狀態(tài)。從另一個角度來看,這也意味著工作者使用的每臺計算機(jī)都是共享服務(wù)器,大大降低了辦公成本。
2分布式文件共享系統(tǒng)主要功能的實現(xiàn)
前文對該系統(tǒng)的實現(xiàn)原理與設(shè)計思路進(jìn)行了分析與論述,本節(jié)內(nèi)容將重點研究該系統(tǒng)中的主要功能模塊實現(xiàn)。在此,將圍繞目錄信息的收集、HTTP服務(wù)器的創(chuàng)建、共享目錄結(jié)構(gòu)信息的發(fā)送與接收、搜索引擎核心功能的架構(gòu)等四個方面來展開設(shè)計、并研發(fā)實現(xiàn)。而實現(xiàn)語言則采用時下非常流行的Python。Python是一種解釋型的、面向?qū)ο蟮?、帶有動態(tài)語義的高級程序設(shè)計語言[ ]。該語言免費、跨平臺,且有著強(qiáng)大的網(wǎng)絡(luò)支持功能,非常適合用來實現(xiàn)本系統(tǒng)。
2.1遍歷指定目錄,以獲取文件及文件夾
使用客戶端軟件來遍歷共享目錄中的文件與文件夾結(jié)構(gòu),是該系統(tǒng)實現(xiàn)的第一步。通過該功能,收集用戶共享目錄中的所有信息,將其保存為指定文件。而當(dāng)用戶目錄中有文件或文件夾發(fā)生異動時,則再次觸發(fā)遍歷的功能,重新對目錄進(jìn)行掃描,并及時更新相應(yīng)文件。因此,該部分功能可分為如下兩步。
2.1.1 實現(xiàn)目錄的遍歷并保存目錄信息
Python語言中遍歷目錄有多種方法,本程序中通過定義一個getfilelist函數(shù)來實現(xiàn)。通過getfilelist函數(shù)將共享目錄中的文件及文件夾進(jìn)行遍歷,并按照具體的索引規(guī)則將目錄結(jié)構(gòu)分行存儲到指定文件中。而用于存儲目錄結(jié)構(gòu)的文件,則以本機(jī)的IP地址為文件名進(jìn)行命名,以便于上傳到服務(wù)器端時進(jìn)行辨識。
以下是實現(xiàn)上述功能的部分代碼。
(1)用于遍歷指定目錄的getfilelist函數(shù)
def getfilelist(filepath):
simplepath = os.path.split(filepath)[1]
returnstr = filepath+"\n"
returndirstr = ""
returnfilestr = ""
filelist = os.listdir(filepath)
for num in range(len(filelist)):
filename=filelist[num]
if os.path.isdir(filepath+"/"+filename):
returndirstr += getfilelist(filepath+"/"+filename)
else:
returnfilestr += filepath+"/"+filename+"\n"
returnstr += returnfilestr+returndirstr
return returnstr+"\n"
(2)用于生成索引文件的creatFile函數(shù)
def creatFile():
ip = socket.gethostbyname(socket.gethostname())
path = WEBDIR #此處路徑在實際應(yīng)用時,將傳入用戶設(shè)置的共享目錄地址
usefulpath = path.replace('\\', '/')
if usefulpath.endswith("/"):
usefulpath = usefulpath[:-1]
if not os.path.exists(usefulpath):
print "path error"
elif not os.path.isdir(usefulpath):
print "it's not a path"
else:
filelist = os.listdir(usefulpath)
o=open("upload/"+ip+".xml","w+") #將生成的文件以本機(jī)IP地址為名,存放在程序的upload目錄下,以備后續(xù)程序?qū)⑵渖蟼鞯椒?wù)器端
o.writelines(getfilelist(usefulpath).replace(usefulpath,"http://"+ip+PROT))
o.close()
print "successed"
通過以上函數(shù)生成的目錄索引內(nèi)容如圖1所示??梢钥吹?,所有共享文件都已經(jīng)以URL的形式出現(xiàn),方便使用者檢索后按相應(yīng)地址下載。
圖1 Creatfile函數(shù)生成的文件預(yù)覽
Fig.1 Creatfile function generated file Preview
2.1.2 監(jiān)聽目錄變化
監(jiān)聽目錄變化,就是在指定的共享目錄中,當(dāng)發(fā)生文件夾或者文件的刪除、修改文件名以及新建對象等操作時,相應(yīng)的程序就會執(zhí)行動作,重新遍歷目錄,并生成目錄列表文件。在此,給出是實現(xiàn)這一功能的實現(xiàn)代碼具體如下。
import os
from creat import creatFile
from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE,IN_MODIFY
wm = WatchManager()
mask = IN_DELETE | IN_CREATE |IN_MODIFY
class PFilePath(ProcessEvent):
def process_IN_CREATE(self, event):
print "Create file: %s " % os.path.join(event.path, event.name)
creatFile()
def process_IN_DELETE(self, event):
print "Delete file: %s " % os.path.join(event.path, event.name)
creatFile()
def process_IN_MODIFY(self, event):
print "Modify file: %s " % os.path.join(event.path, event.name)
creatFile()
if __name__ == "__main__":
notifier = Notifier(wm, PFilePath())
wdd = wm.add_watch('./../Documents', mask, rec=True)
while True:
try :
notifier.process_events()
if notifier.check_events():
notifier.read_events()
except KeyboardInterrupt:
notifier.stop()
break
2.2創(chuàng)建HttpServer,以Web形式共享指定目錄
加入分布式共享系統(tǒng)的每臺計算機(jī)都會是一臺獨立的文件分享服務(wù)器。因而為簡便起見,此處將直接采用對平臺無具體要求且廣受關(guān)注的HTTP超文本傳輸協(xié)議。
基于設(shè)計方案,將在客戶端上建立一個簡單HTTP服務(wù)器,并將用戶共享的目錄處于該服務(wù)范圍內(nèi),以方便其他用戶通過HTTP協(xié)議下載共享文件。
利用Python語言建立HTTP服務(wù)非常簡單,其實現(xiàn)代碼具體如下[ ]。
import SimpleHTTPServer
import SocketServer
import os
WEBDIR = "/home/zz/Documents" #此處傳入用戶設(shè)置的共享目錄
PORT = 8 000 #此處設(shè)置HTTP服務(wù)器的服務(wù)端口
os.chdir(WEBDIR)
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
此時,共享目錄已經(jīng)可以通過http://主機(jī)IP:8000的形式進(jìn)行訪問了。
2.3發(fā)送共享目錄結(jié)構(gòu),以方便服務(wù)器進(jìn)行文件檢索
當(dāng)一臺計算機(jī)加入分布式共享系統(tǒng)后,客戶端程序會自動索引共享目錄中的文件夾與文件,并將其直接生成一個索引文件。此時要做的就是將該索引文件發(fā)送到服務(wù)器端,從而在后續(xù)環(huán)節(jié)中利于有關(guān)檢索用途的實現(xiàn)。
在Python語言中,文件的傳輸可以使用其Socket模塊來實現(xiàn)[4, ],具體也分為兩個部分:一是客戶機(jī)上的客戶端負(fù)責(zé)發(fā)送指定文件;二是服務(wù)器端負(fù)責(zé)接收文件,并將文件存放到指定位置。以下將分別給出客戶端與服務(wù)器端的實現(xiàn)代碼。
2.3.1 客戶端
在客戶端的實現(xiàn)過程中,需要考慮的問題是:向誰發(fā)送文件,發(fā)送什么文件,最關(guān)鍵的則是怎樣發(fā)送文件,以下給出的是用于向服務(wù)器端發(fā)送文件的sendfile函數(shù)。該函數(shù)將在每次createfile函數(shù)(即生成目錄索引函數(shù))運行后調(diào)用,以確保服務(wù)器端接收到的目錄索引文件就是最新的版本。該功能實現(xiàn)的主要代碼如下。
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def sendfile(filename):
print "server ready, now client sending file~~"
f = open(filename, 'rb')
while True:
data = f.read(4 096)
if not data:
break
s.sendall(data)
f.close()
time.sleep(1)
s.sendall('EOF')
print "send file success!"
2.3.2 服務(wù)器端
服務(wù)器端只需要對指定端口進(jìn)行偵聽,當(dāng)客戶端得到發(fā)送文件的命令請求時,啟動相應(yīng)功能進(jìn)行文件接收即可。具體功能實現(xiàn)的主要代碼如下。
class MyTcpServer(SocketServer.BaseRequestHandler):
def recvfile(self, filename):
print "starting reve file!"
f = open(filename, 'wb')
self.request.send('ready')
while True:
data = self.request.recv(4 096)
if data == 'EOF':
print "recv file success!"
break
f.write(data)
f.close()
def handle(self):
print "get connection from :",self.client_address
while True:
try:
data = self.request.recv(4 096)
print "get data:", data
if not data:
print "break the connection!"
break
else:
action, filename = data.split()
if action == 'get':
self.sendfile(filename)
else:
print "get error!"
continue
except Exception,e:
print "get error at:",e
2.4建立主服務(wù)器搜索引擎,以實現(xiàn)分布式文件共享檢索
當(dāng)加入分布式共享系統(tǒng)的用戶計算機(jī)向服務(wù)器提交了包含共享目錄索引的文件后,接下來就將由服務(wù)器提供搜索反饋服務(wù)了。一般用戶只需要在瀏覽器中輸入服務(wù)器提供的搜索頁面的地址,并在其提供的搜索頁面中輸入關(guān)鍵字,服務(wù)器就會在由各個客戶機(jī)提供的索引目錄的文件中進(jìn)行檢索。當(dāng)符合條件的結(jié)果出現(xiàn)時,則由服務(wù)器給出反饋頁面,同時提供轉(zhuǎn)向相應(yīng)結(jié)果的下載鏈接。
如何建立一個Web服務(wù)器以及提供一個包含搜索框的HTML頁面在這里就不做贅述了,以下主要討論當(dāng)搜索關(guān)鍵字傳入后,Python在包含有索引目錄的文件中進(jìn)行檢索并反饋相應(yīng)結(jié)果的過程。這里用到的主要是Python的文本處理功能,具體實現(xiàn)代碼如下。
def search_result(filename,searchString):
#filename是指需要檢索的文件名,searchString是用戶傳入的檢索關(guān)鍵字
sys.setdefaultencoding('utf-8')
f = open(filename, 'rb')
s_s =searchString
result=''
for i in f:
if s_s in i:
result+=i.decode('utf-8')
return result
此時,只需調(diào)用search_result()函數(shù),遍歷包含索引目錄文件的文件夾,傳入索引文件名及關(guān)鍵字即可。
3分布式文件共享系統(tǒng)功能總結(jié)與展望
至此,一個基于Python語言的分布式文件共享系統(tǒng)已經(jīng)成功實現(xiàn)。用戶可以通過安裝一個小的客戶端,隨時加入到文件共享的隊伍中來,而其他使用者只需要通過一個簡單的搜索功能,就可以獲取到相應(yīng)的文件。該系統(tǒng)與FTP相比更直觀,與Email相比更快捷,與云協(xié)作軟件相比更安全,與U盤拷貝相比效率大大提升,且共享數(shù)據(jù)規(guī)模則要遠(yuǎn)遠(yuǎn)超出以上各類方式。筆者以3顆星為滿分進(jìn)行評價,從獲取效率、傳輸方式、共享范圍以及數(shù)據(jù)安全性等四項共享指標(biāo)出發(fā),將其與時下常見的各類共享方式進(jìn)行比較,得出的結(jié)果可參見表1。
表1各類文件共享形式比較(滿分為三顆★)
Tab.1 Comparison of various forms of file sharing (out of three stars)
獲取效率高 傳輸方式便捷 共享范圍廣 數(shù)據(jù)安全性高
Email ★ ★★ ★★ ★★★
FTP ★ ★★ ★★ ★
即時通軟件 ★★★ ★★★ ★ ★★
云盤類軟件 ★★★ ★★★ ★★ ★★
U盤 ★ ★ ★ ★★★
分布式共享 ★★★ ★★★ ★★★ ★★★
當(dāng)然,當(dāng)前設(shè)計的系統(tǒng)還只能通過文件名來進(jìn)行檢索,很多方面還不夠完善,在后續(xù)功能拓展方面,可以加入文件內(nèi)容檢索、文件預(yù)覽等功能,使得檢索結(jié)果更為精準(zhǔn)、而且更趨人性化,在檢索算法上將會更加地優(yōu)化,使之能適應(yīng)企業(yè)級規(guī)模的發(fā)展需要。