日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
創(chuàng)新互聯(lián)Python教程:基于tornado服務(wù)器實(shí)現(xiàn)文件上傳和下載

文件上傳的服務(wù)端技術(shù)解析

常言到,愛有多深、恨有多切。tornado服務(wù)器就是這樣一個(gè)矛盾體,它的缺點(diǎn)和它的優(yōu)點(diǎn)一樣,顯著且強(qiáng)烈。有人認(rèn)為,文件上傳是tornado的重大缺陷之一,它把用戶上傳的文件存放在內(nèi)存中——這意味著多用戶同時(shí)上傳文件的話,內(nèi)存的開銷會(huì)急劇增加。不過我倒是覺得,這反倒讓很多事情變得簡(jiǎn)單了,比如,你想對(duì)用戶上傳的內(nèi)容做處理的話,不用再打開文件了,因?yàn)閮?nèi)容就在內(nèi)存中。再者說,在tornado的異步機(jī)制下,我不確定真的能夠多用戶同時(shí)上傳文件。這是一個(gè)有趣的問題。

好了,言歸正傳吧。假定文件上傳的表單如下:


    
    
    

機(jī)制是允許一次上傳多個(gè)文件的。這里有幾個(gè)問題需要特別說明一下。

在提交表單之前,需要為form指定action和method的屬性值,如果是上傳文件,還要設(shè)置enctype=“multipart/form-data”。這三個(gè)屬性,可以寫在html中,也可以在submit之前用js的方法為其賦值。

文件瀏覽是file類型的input標(biāo)簽自備的功能,程序員無法在瀏覽器框架內(nèi)操作本地文件。該標(biāo)簽的name屬性,是用來區(qū)別于其他文件的標(biāo)識(shí),不是文件名,也不是文件對(duì)象,更不是文件內(nèi)容。

上面的表單被提交到/demo/upload(假定上傳的第1個(gè)文件名為dqd.jpg,第2個(gè)文件名為intro.png),這個(gè)請(qǐng)求的對(duì)象中包含files字典,上傳的全部文件的信息都包含在這個(gè)結(jié)構(gòu)中。我們來看看這個(gè)request.files的真實(shí)面貌:

def post(self):
    print self.request.files.keys() # [u'want_to_upload_file_1', u'want_to_upload_file_2']
    print type(self.request.files['want_to_upload_file_1']) # list,長(zhǎng)度為1
    meta_file_1 = self.request.files['want_to_upload_file_1'][0]
    print meta_file_1.keys() # ['body', 'content_type', 'filename']
    print len(meta_file_1['body']) # 31492,文件長(zhǎng)度
    print meta_file_1['content_type'] # image/jpeg
    print meta_file_1['filename'] # dqd.jpg

有了這些素材,我們就可以無所不能地應(yīng)對(duì)客戶需求了。比如,不做任何處理,僅僅用原文件名保存在指定路徑下(假設(shè)保存在/static/image/wiki目錄下):

PROJECT_PATH = os.path.split(os.path.realpath(__file__))[0]
upload_path = os.path.join(PROJECT_PATH, 'static', 'image', 'wiki')
file_name = os.path.join(upload_path, meta_file_1['filename'])
with open(file_name, 'wb') as fp:
    fp.write(meta_file_1['body'])

很多時(shí)候,需要對(duì)用戶上傳的文件重命名(比如,用時(shí)間戳為文件名),但文件后綴名不變。

fn, ext = os.path.splitext(meta_file_1['filename'])
fn = '%d%s' % (time.time()*1000, ext)
file_name = os.path.join(upload_path, fn)

如果需要對(duì)用戶上傳的文件類型做檢查,請(qǐng)使用文件的content_type,而不是文件的擴(kuò)展名,因?yàn)榍罢吒?guī)范。比如,JPEG類型的圖片文件,其后綴名可能是.jpg|.jpeg|.JPG|.JPEG中的一種,而前者只有“image/jpeg”一種表示法。

關(guān)于文件的content_type,網(wǎng)上資料多如牛毛,請(qǐng)自行搜索。

處理用戶上傳的圖片文件時(shí),除了限制文件大小,有時(shí)候還要做縮放處理,甚至一并生成縮略圖,此時(shí)就需要將文件內(nèi)容轉(zhuǎn)成易于處理的圖像對(duì)象,比如,pil的Image。

from PIL import Image
import StringIO
pilImg = Image.open(StringIO.StringIO(meta_file_1['body']))
print pilImg.size

至于如何縮放、如何保存為文件,請(qǐng)自行檢索相關(guān)資料。

基于Ajax技術(shù)實(shí)現(xiàn)的文件上傳客戶端

假定上傳文件的表單是這樣的:


    
    

方法1:使用 ajaxfileupload.js


方法2:僅依賴 jquery.js

文件下載的服務(wù)端技術(shù)解析

相對(duì)于上傳,文件的下載就簡(jiǎn)單得多。只需要記住兩點(diǎn):開始前告訴瀏覽器要傳輸?shù)奈募愋?,結(jié)束前對(duì)瀏覽器說拜拜。文件類型并不是固定的,需要根據(jù)文件的實(shí)際情況來選擇。詳情請(qǐng)自行檢索。

def get(self):
    self.set_header ('Content-Type', 'application/octet-stream')
    with open(filename, 'rb') as f:
        while True:
            data = f.read(buf_size)
            if not data:
                break
            self.write(data)
    self.finish()

配合seek命令,可以實(shí)現(xiàn)更復(fù)雜的下載請(qǐng)求,比如,斷點(diǎn)續(xù)傳、分塊下載、ajax異步請(qǐng)求等。

眾多python培訓(xùn)視頻,盡在python創(chuàng)新互聯(lián)教程,歡迎在線學(xué)習(xí)!


新聞標(biāo)題:創(chuàng)新互聯(lián)Python教程:基于tornado服務(wù)器實(shí)現(xiàn)文件上傳和下載
新聞來源:http://www.dlmjj.cn/article/dhigedo.html