1. 程式人生 > >基於django的文件管理模組

基於django的文件管理模組

一、需求

在網路運維平臺的設計中使用者可能會產生不少的文件,這就需啊喲來做一個對文件管理的功能。

主要實現的目標有:單個文件上傳,批量上傳;單個文件下載,批量下載;限制上傳文件的大小,限制同時上傳文件的數量。

二、選擇文件儲存方式

文件上傳的時候有幾種方式,分別是:

1.直接把文件儲存到資料庫中(這個最簡單粗暴,對資料庫的壓力也是最大的一個,也最容易帶來更多的問題所以不選擇這種做法)

2.通過nginx或者Apache搭建檔案伺服器,由django進行許可權判斷,文件上傳下載的部分交由nginx來處理(據說這個是最好的方案),但是由於本人對nginx並不熟悉,加之後期部署方面的原因,並沒有選擇這種方法。

3.文件通過django自帶的機制上傳到指定為資料夾,檔名路徑等一些基本資訊儲存到資料庫中,通過查詢資料庫中的資訊來找到檔案的存放位置進而對文件進行操作。(本文采用的就是這種方式)

三、資料庫設計

資料庫採用postgresql建了3張表分別儲存左側ztree資料夾樹、右側datatable、限制檔案大小上傳個數

ft_directory(左側資料夾樹):主要包含:名稱、別名、描述、uuid、父節點、層級等欄位

ft_attach(儲存檔案資訊的欄位):檔名、關鍵字、描述、下載次數、上傳者(預留欄位現在並沒有用)、檔案大小、檔案路徑等欄位

ft_directory_setting:這個表比較簡單僅包含配置關鍵字、配置數值、描述這三個主要欄位

注:每個表都需要有的建立時間更新時間等欄位在這裡不再列出

四、jQuery-file-upload

為了使文件上傳的時候實現多檔案同時上傳,並提高上傳效果,採用jQuery-file-upload外掛在前端實現對檔案的處理。

jQuery-file-upload的基本用法:

初始化jQuery-file-upload

   $('#fileupload').fileupload();


一些基本配置

                  url: '/feature/attach/dt/create/fild/',
                    singleFileUploads: false, //一次上傳多個檔案
                    autoUpload: false,
                    maxFileSize: parseInt($('#file_size').val()) * 1024 * 1024,
                    maxNumberOfFiles: parseInt($('#file_count_size').val()),
                    messages: {
                        maxFileSize: '超過允許的最大值!',
                        maxNumberOfFiles: '上傳的檔案數量超過允許的最大值!'
                    },

jQuery提供了不少的事件,我們僅僅需要使用他提供的一部分就好了

processdail:該事件提供了當檔案上傳時出現錯誤的時候執行的一些方法。在本例中是當文件大小或者同時上傳的文件數不滿足條件的時候執行

應當注意的是如果選中多個檔案,這個方法將要執行多次,選中幾個文件執行幾次。

processfail: function (e, data) {
    //單個檔案上傳失敗
    if (self.datafile == undefined) {
        self.datafile = data
    }
    var currentFile = data.files[data.index];
    if (data.files.error && currentFile.error) {
        if (currentFile.error == '上傳的檔案數量超過允許的最大值!') {
            $('#warning_file').css('display', 'block').html('').prepend(currentFile.error + '<br>')
        } else {
            $('#warning_file').css('display', 'block').prepend(currentFile.name + '    ' + currentFile.error + '<br>')
        }
    }
},

processdone:該事件是在單個檔案處理圓滿結束的時候執行,在這個方法之後dada引數將加上submit()方法可通過  data.submit()的方式直接把檔案提交到伺服器,同時如果選中有多個file則執行多次,我們可以把這個值賦到 self.datafile上然後在使用者點選提交按鈕的時候執行 self.datafile.submit()把files和整個表單提交到後臺。

progressall:該事件是上傳進度事件通過該事件可設定上傳進度條

change:事件當選中的file發生改變的時候執行

例:

.bind('fileuploadchange', function (e, data) {
    $('#warning_file').css('display', 'none').html('');
    $('#progresss').css('width', '0%');
    self.init_file_list(data);
});


當選中的file改變的時候進度條置零,清空警告框內容呼叫函式處理下一步操作

五、設計思路

當用戶點選提交按鈕的時候,執行 data.submit()通過jQuery-file-upload的機制把整個form表單提交到後臺,表單中也可以包含我們新增的一些資料。

一開始的時候只需要在processdone:事件執行的時候,把data放到一個使用者點選提交時能夠訪問到的地方,self.datafile是一個不錯的選擇。

1.初始化self.datafile


當用戶選擇檔案又沒有錯誤的時候 以下函式將會執行。

processdone可以執行很多次,但是我們只在self.datafile為undefined的時候執行一次,這樣既能保證self.datafile可以使用self.datafile.submit()又不影響後續操作。

processdone:function(e, data) {
    if (self.datafile == undefined) {
        self.datafile = data;
    }
},


這樣的話可以滿足大部分情況,但是有些情況不適用,比如使用者第一次選擇就選擇了多餘規定個數的檔案,這樣的話就沒有一個檔案是圓滿完成的狀態,processdone就不會執行。不過這樣的話則觸發了另外一個事件

prosessfail:單個檔案處理失敗的回撥,當有檔案不滿足設定的條件的時候,執行這個方法裡面的內容同時在這個方法中,data也是可以實現data.submit()的,這個時候我們需要讓self.datafile= data這樣就能保證不管什麼情況下當用戶點選提交按鈕的時候,self.datafile.submit()都是可用的.

同時在這個函式裡處理一些資訊,給使用者一些警告。

processfail: function (e, data) {
    //單個檔案上傳失敗
    if (self.datafile == undefined) {
        self.datafile = data
    }
    var currentFile = data.files[data.index];
    if (data.files.error && currentFile.error) {
        if (currentFile.error == '上傳的檔案數量超過允許的最大值!') {
            $('#warning_file').css('display', 'block').html('').prepend(currentFile.error + '<br>')
        } else {
            $('#warning_file').css('display', 'block').prepend(currentFile.name + '    ' + currentFile.error + '<br>')
        }
    }
},


2.允許使用者多次選擇

當用戶選擇了檔案之後,突然發現別處還有一個檔案沒有選,需要再次選擇,但是使用者並不想丟棄一開始選擇的檔案,這樣就需要有一個地方能夠暫存使用者一開始選擇的檔案。在這裡我們選擇用self.datafile來暫存使用者選擇的檔案,當用戶選擇檔案之後有一個change事件執行的回撥,當選中的檔案發生變化的時候就執行這個函式。


第一次選擇的檔案


我們看到有一個重複選項,第三章的那個檔案。那我們來看看被選中的結果


可以看到我們已經把重複的選項過濾掉了,而且相同的檔案是丟棄了第二次選中的那個檔案。

怎麼做的呢?看下面

.bind('fileuploadchange', function (e, data) {
    $('#warning_file').css('display', 'none').html('');
    $('#progresss').css('width', '0%');
    self.init_file_list(data);
});

當input內選中的檔案發生改變時執行上面的程式碼,並呼叫init_file_list對選中的檔案進行處理,丟棄重複的檔案。

在init_file_list被呼叫的時候傳入當前選中的檔案,該函式將會自動處理好資料,並存到self.datafile裡。

init_file_list: function (data) {
    var self = this;
    if (self.datafile == undefined) {
        self.listen_remove_filename = false;
        self.show_file_list(data, new Date().getTime())
    } else {
        //合併陣列,並去掉重複的資料
        self.datafile.files = self.datafile.files.concat(data.files);
        data.files = self.datafile.files;
        var file_arr = [];
        var temp = {};
        for (var i = 0; i < data.files.length; i++) {
            if (!temp[data.files[i].name]) {
                temp[data.files[i].name] = 1;
                file_arr.push(data.files[i])
            }
        }
        data.files = self.datafile.files = file_arr;
        //合併完陣列之後,呼叫函式,把檔名顯示到待顯示區
        self.listen_remove_filename = false;
        self.show_file_list(self.datafile, new Date().getTime())
    }
},

               注:在這一步合併陣列之後對陣列中的資料進行篩選,去除重複的資料,以上寫法是去除後來加入的資料,

如果想要後一次的資料覆蓋前一次的資料主需要在陣列用             concat 連線到時候換一下連個引數的位置即可

對上傳的檔案進行處理完成之後show_file_list()方法,把選擇的檔案的名字顯示到頁面上。

show_file_list: function (data, datetime) {
    //此函式把被選中的檔名字顯示到指定區域
    var self = this;
    $('#fileupload_file_name').html('');
    for (var i = 0; i < data.files.length; i++) {
        var show_file_name = '<div  name="div' + String(data.files[i].name) + '"><p class="col-lg-9"> ' + data.files[i].name + '</p><p class="col-lg-3"><span name="del' + datetime + '" title="' + data.files[i].name + '" style="cursor: pointer"><i class="glyphiconglyphicon-remove"></i></span></p></div>'
        $('#fileupload_file_name').prepend(show_file_name);
    }
    if (self.listen_remove_filename != true) {
        $('[name="del' + datetime + '"]').click(function () {
            //繫結點選事件,
            if (self.datafile) {
                for (var i = self.datafile.files.length - 1; i >= 0; i--) {
                    if (self.datafile.files[i].name == this.title) {
                        self.datafile.files.splice(i, 1);
                        data.files.splice(i, 1);
                        break
                    }
                }
                $('[name="div' + this.title + '"]').remove();
            }
            //當點選刪除時呼叫驗證函式,驗證檔案大小和數量是否合適。
            var err_msg = self.validation_file(self.datafile);
            if (err_msg.length == 0) {
                $('#warning_file').css('display', 'none').html('')
            } else {
                $('#warning_file').html('').css('display', 'block').html(err_msg.join(''))
            }
        });
        self.listen_remove_filename = true
    }
},

3.使用者刪除部分選中的檔案

當用戶選擇的檔案有不滿足條件的時候


當用戶選擇檔案過多或者有些檔案過大的時候,使用者想刪除幾個已選的檔案以通過驗證,這個時候jquery-file-upload提供的驗證又不能直接使用了。

所以就寫了個驗證的函式,只需要把需要驗證的資料傳入即可返回驗證結果,這個函式也用在請提交前的驗證上。

validation_file: function (data) {
    var file_fize = parseInt($('#file_size').val());
    var file_count_size = parseInt($('#file_count_size').val());
    var error_msg = [];
    if (data && data instanceof Object) {
        for (var i = 0; i < data.files.length; i++) {
            if (parseInt(data.files[i].size) > file_fize * 1024 * 1024) {
                error_msg.push(data.files[i].name + "超過指定的大小<br>")
            }
        }
        if (data.files.length > file_count_size) {
            error_msg.push('上傳檔案數量超過限制<br>')
        }
    }
    return error_msg
},


4.使用者點選提交按鈕開始上傳檔案

先說檔案上傳的機制,當用戶選中左側樹的時候便制定了要上傳的資料夾,使用者點選上傳按鈕選擇檔案,下方有是否替換檔案的選項,如果選擇了替換檔案則覆蓋上次上傳的檔案,不選的話則不替換。但是這個時候如果不選擇替換檔案選項,而相同資料夾下又有同名檔案的話就需要給前端報個錯誤,提示使用者那些檔案後臺已經存在,請使用者重新選擇。

當相同資料夾有同名檔案的時候後臺返回一條錯誤訊息


如果選中了替換按鈕則直接把檔案傳送到後臺。

                            if (alone == undefined) {
                                $.get('/feature/attach/dt/create/fild/', get_fild_data, function (res) {
                                    var result = JSON.parse(res);
                                    if (result.error_msg) {
                                        console.log(result.error_msg)
                                        alert(result.error_msg)
                                    } else if (result.success && result.success == true) {
                                        sub_self.datafilesbumit()
                                    }
                                });
                            } else if (alone == 'checked') {
                                sub_self.datafilesbumit()
                            }

以下是jQuery-file-upload的上傳檔案的方法

                    datafilesbumit: function () {
                        var self = this
                        self.datafile.submit().success(function (result, textStatus, jqXHR) {
                            var result = JSON.parse(result);

                            if (result.error_msg) {
                                alert(result.error_msg);
                            }
                            if (result.success) {
                                $('#warning_file').html('');
                                $('#warning_file').css('display', 'block').prepend(result.success);
                                self.datafile = undefined;
                                self.refresh();
                                $modal.modal('hide');
                            }
                        })

                    },


後臺程式碼:

一、左側資料夾部分,

1.左側資料夾樹部分重寫了delete方法,從資料據庫中找到滿足條件的資料刪除,再查到這個資料夾的真實路徑,刪除這個空資料夾

2.建立,按照通用套路重寫save_callback方法,在create的時生成一個uuid插入資料庫。其他的基本不變

3.編輯,建立一樣的做法,重寫的save_callback具有建立和編輯兩者的功能。

另:通過重寫ztree元件的_init_ztree方法,實現空資料夾才可顯示出刪除按鈕,

二、檔案上傳部分

1.上傳

       一開始在寫這個上傳檔案的時候為了減少請求數量,在前端對檔案進行處理之後,直接把檔案發到後臺,再檢查同一資料夾是否有重複的選項如果有重複的檔案再返回前端,並對已經發到後臺的檔案進行不儲存操作。

這樣如果有重複的檔案時無疑浪費了流量。

       後來針對這個問題改進為了現在這個方案

       當後端接收到使用者傳送的檔案時,需要把檔案儲存到指定的資料夾下在儲存之前需要對檔案進行base64編碼,親測:如果不編碼直接儲存,下載下來檔案會出現損壞。

2.下載檔案

下載之前需要先進行base64編碼,由於python自帶了base64模組,所以程式碼並不複雜

pk = kwargs.get('pk')
obj_file_record = self.model.objects.get(pk=pk)
str_path = obj_file_record.file_path
arr_path = str_path.split('_')
# path = '\\'.join(arr_path)
# baseDir = os.path.dirname(os.path.abspath(__name__))  # 獲取系統資料夾路徑
file_dir = os.path.join(net_auto.settings.MEDIA_ROOT, '\\'.join(arr_path))  # 獲取檔案路徑
file_path = os.path.join(file_dir, obj_file_record.name)

def file_iterator(file_name, chunk_size=512):
    with open(file_name) as f:
        while True:
            c = base64.b64decode(f.read(chunk_size))
            if c:
                yield c
            else:
                break
response = StreamingHttpResponse(file_iterator(file_path))
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename=%s' % obj_file_record
new_obj = self.model.objects.get_or_create(id=pk)[0]
new_obj.downs = new_obj.downs + 1
new_obj.save()

3.批量下載

批量下載的時候要先建立一個臨時資料夾,資料夾的名字用生成的uuid

temp_folder = shortuuid.uuid()
temp_root_folder = os.path.join(net_auto.settings.MEDIA_ROOT, 'temp', temp_folder)
os.makedirs(temp_root_folder)
# 批量下載的時候先建一個臨時資料夾

在打包壓縮之前需要把伺服器上儲存的經過base64編碼過的檔案解碼到指定資料夾,這裡是把它們按照儲存時的路徑解碼到用uuid命名的那個臨時資料夾下
如果儲存下載的時候不經過base64編碼解碼,等下載到本地之後會出錯

def decoding_file(self, pk, temp_folder, temp_root_folder):
    # 把檔案解碼到指定目錄下
    for i in range(len(pk)):
        file_obj = self.model.objects.filter(id=pk[i])[0]
        uuid_path = file_obj.file_path.split('_')
        for j in range(len(uuid_path)):
            uuid_file = uuid_path[j]
            folder_name = Directory.objects.filter(uuid=uuid_file)[0].name
            filename = os.path.join(temp_root_folder, str(folder_name))
            if os.path.exists(filename) == False:
                os.makedirs(filename)
                temp_root_folder = temp_root_folder + "\\" + folder_name
            elif os.path.exists(filename) == True:
                temp_root_folder = temp_root_folder + "\\" + folder_name
        temp_file_path = os.path.join(temp_root_folder, file_obj.name)
        file_path = os.path.join(net_auto.settings.MEDIA_ROOT, '\\'.join(file_obj.file_path.split('_')),
                                 file_obj.name)  # 獲取檔案路徑
        with open(file_path) as f:
            temporary_file = open(temp_file_path, 'wb')
            temporary_file.write(base64.b64decode(f.read()))
            temporary_file.close()
        temp_root_folder = os.path.join(net_auto.settings.MEDIA_ROOT, 'temp', temp_folder)  # 初始化臨時資料夾根目錄,以便進入下次迴圈
        # 把檔案解碼到指定檔案下
    return temp_root_folder

用uuid命名資料夾的原因是的原因是,我不知道會不會有多使用者同時下載檔案的情況,也不知道把臨時檔案放一個相同的資料夾下,
這些使用者下載檔案的時候會不會相互影響,索性生成個uuid,每次批量下載的時候臨時資料夾都有一個唯一的名字,即使多使用者下載也沒關係。
以下是解碼要下載的檔案到指定檔案,並壓打包成壓縮檔案的過程

pk = kwargs.get('pk').split('_')
temp = tempfile.TemporaryFile()
# 批量下載的時候先建一個臨時檔案
temp_folder = shortuuid.uuid()
temp_root_folder = os.path.join(net_auto.settings.MEDIA_ROOT, 'temp', temp_folder)
os.makedirs(temp_root_folder)
# 批量下載的時候先建一個臨時資料夾
archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED)
temp_root_folder = self.decoding_file(pk, temp_folder, temp_root_folder)
# 呼叫decoding_file函式解碼檔案到指定的臨時資料夾裡
filename = os.path.join(net_auto.settings.MEDIA_ROOT, 'temp', temp_folder)
# 臨時資料夾存放路徑
# 這裡開始打包壓縮filename臨時資料夾的內容
pre_len = len(os.path.dirname(filename))
for parent, dirnames, filenames in os.walk(filename):
    for filename in filenames:
        pathfile = os.path.join(parent, filename)
        arcname = pathfile[pre_len:].strip(os.path.sep)  # 相對路徑
        archive.write(pathfile, arcname)
archive.close()
# 壓縮臨時目錄下的檔案結束
# 對要下載的壓縮檔案加一些預設名字什麼的
datatime = time.strftime("%Y-%m-%d--%H-%M-%S", time.localtime(time.time()))
wrapper = FileWrapper(temp)
response = StreamingHttpResponse(wrapper)
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename=%s' % datatime + '.zip'
shutil.rmtree(temp_root_folder)  # 刪除臨時資料夾
temp.seek(0)
for i in pk:
    new_obj = self.model.objects.filter(id=i)[0]
    new_obj.downs = new_obj.downs + 1
    new_obj.save()


解碼檔案到指定資料夾的函式

def decoding_file(self, pk, temp_folder,temp_root_folder):
    # 把檔案解碼到指定目錄下
    for i in range(len(pk)):
        file_obj = self.model.objects.filter(id=pk[i])[0]
        uuid_path =file_obj.file_path.split('_')
        for j in range(len(uuid_path)):
            uuid_file = uuid_path[j]
            folder_name =Directory.objects.filter(uuid=uuid_file)[0].name
            filename =os.path.join(temp_root_folder, str(folder_name))
            if os.path.exists(filename) == False:
               os.makedirs(filename)
                temp_root_folder =temp_root_folder + "\\" + folder_name
            elif os.path.exists(filename) == True:
                temp_root_folder =temp_root_folder + "\\" + folder_name
        temp_file_path =os.path.join(temp_root_folder, file_obj.name)
        file_path =os.path.join(net_auto.settings.MEDIA_ROOT, '\\'.join(file_obj.file_path.split('_')),
                                file_obj.name)  # 獲取檔案路徑
        with open(file_path) as f:
            temporary_file = open(temp_file_path, 'wb')
           temporary_file.write(base64.b64decode(f.read()))
            temporary_file.close()
        temp_root_folder =os.path.join(net_auto.settings.MEDIA_ROOT, 'temp', temp_folder)  # 初始化臨時資料夾根目錄,以便進入下次迴圈
        # 把檔案解碼到指定檔案下
    return temp_root_folder

以上就是文件管理的主要部分
下面還有一些關於左側資料夾樹的東西


這個資料夾數繼承自ztree元件重寫了_init_ztree方法,如果該資料夾下有檔案,則不允許出現刪除按鈕。沒有檔案的話就顯示出刪除按鈕
同一資料夾下不允許出現名字相同名字的文夾
通過在save_callback檢查是否有相同名字檔案,如果有就丟擲異常

if kwargs['action'] == 'create':
    obj.uuid = shortuuid.uuid()
    if len(get_obj) > 1:
        obj.delete()
        raise Exception(u'在同一資料夾下,已存在相同的目錄')
    else:
        obj.save()
        self.init_folder(self, new_arr, *args, **kwargs)
else:
    obj.save()
    self.init_folder(self, new_arr, *args, **kwargs)

文件引數設定通過設定文件引數來限制上傳檔案的大小和上傳個數


總結:
至此,這個文件管理的部分就完成了。通過這部分內容學到了不少的東西,對自身也有了不少的提高;通過文件的撰寫,發現之前設計的不足。
並對同類的外掛的用法有了一定的瞭解。

相關推薦

基於django管理模組

一、需求 在網路運維平臺的設計中使用者可能會產生不少的文件,這就需啊喲來做一個對文件管理的功能。 主要實現的目標有:單個文件上傳,批量上傳;單個文件下載,批量下載;限制上傳文件的大小,限制同時上傳文件的數量。 二、選擇文件儲存方式 文件上傳的時候有幾種方式,分別是:

基於Django 1.11 自解+補完 學習django ---part1

學習django 很長一段時間了 國內的資料少之甚少,加之英文文件sei也不願意看或者看不懂,使得學習更加陡峭,so準備研究官網案例結合我的學習經歷,進行姿勢補全 *Tip:本文基於Django文件1

disconf實踐(三)基於XML的分布式配置管理,自動reload

blog exce conf redis 信息 exceptio res pan ram 上一篇介紹了基於xml的非自動reload的分布式配置文件管理,這一篇介紹自動reload的方式(基於disconf實踐二)。 1. 修改RedisConfig.java 1 pa

基於 Laravel 的 管理

info isf laravel 雲存儲 完成 function 根目錄 pat ont   以 laravel 5.5 為例,框架集成了文件系統和雲存儲功能   可以實現文件夾列表、創建、重命名、刪除,文件列表、上傳、重命名、刪除等操作 一、先進行配置   在 con

在滴滴雲DC2上基於Gitbook+Nginx構建輕量級管理服務

介紹 工作中經常會遇到團隊文件如何管理的問題,Atlassian之類的太複雜,很多時候並沒有成千上萬級別的文件需要管理,可能只有幾百篇的文章需要管理,今天在滴滴雲上給大家演示一下如何快速搭建一個輕量級的文件管理服務。 準備工作 在滴滴雲上申請一個DC2伺服器:滴

django官方——管理器(資料庫操作介面)

控制自動管理器型別¶ 本文已經談了許多 Django 為你建立的管理器類:`預設管理器`_ 和用於 操作關聯物件 的“簡明”管理器。但是 Django 的執行還需要一些其它的簡明管理器。這些自動建立的管理器是 django.db.models.Manager 的例項。 本節我們會使用“自動管理器”來指代

【bzoj3289】Mato的管理 離散化+莫隊算法+樹狀數組

逆序對 sample 單位 oid 逆序 cmp family += efi 原文地址:http://www.cnblogs.com/GXZlegend/p/6805224.html 題目描述 Mato同學從各路神犇以各種方式(你們懂的)收集了許多資料,這些資料一共有n份

Linux 中最常用的目錄及管理命令

得到 bzip2 文件夾 操作 管理命令 內容 fig find work 一、查看文件的命令  對於一個文本文件,在linux中有多種查看方式來獲知文件內容,如直接顯示整個文本內容、分頁查看內容、或者只查看文件開頭或末尾的部分內容。在linux可以用不同的命令來實現。  

php簡單管理器——php經典實例

false tro eth put head 遍歷目錄 == border iconv <html> <head> <title>文件管理</title> <meta cha

基於本地系統的LocalDB

root 構造函數 -s oot region pan pri 指定 void 零、前言   之前寫一些小工具的時候,需要用到數據存儲方面的技術,但是用數據庫又覺得太大了,本地文件存儲txt文件存儲又不是很規範,於是乎想到了去編寫一個簡單的基於本地文件系統的數據存儲庫,暫且

JDFS:一款分布式管理實用程序第一篇(線程池、epoll、上傳、下載)

cpu nload tree 程序 fun 是的 發的 fop let 一 前言   截止目前,筆者在博客園上面已經發表了3篇關於網絡下載的文章,這三篇博客實現了基於socket的http多線程遠程斷點下載實用程序。筆者打算在此基礎上開發出一款分布式文件管理實用程序,截止目

管理

intent bmp todo lower 事件 and toast rep size 主類 public class main extends ListActivity/*繼承這個類就可以直接進入安卓文件目錄*/{ private static final String

Moodle 中文 API 之 管理API

reverse string bit /dev/ empty cte extra 回調函數 安全 File API 文件管理 文件夾 1. 概述 2. 文件域 2.1 命名文件域 3. 提供文件給用戶 4. 從用戶那獲取文件 5. 樣例

修改後的小米管理器(去掉遠程管理)

detail ext watermark bsp http font profile 修改 avi 最近項目要用到文件管理,就找來小米的開源文件管理代碼,刪掉了遠程管理代碼,只有文件管理. 效果圖如下: 源碼下載地址:http://download.csdn.ne

磁盤及管理系統入門(一)

fs 硬盤 uefi&gpt linux磁盤及文件系統管理初步目錄 1.磁盤及文件系統管理 2.機械磁盤結構 3.mknod命令 4.parted命令 5.GPT分區&UEFI 6.二進制單位Linux系統管理磁盤分區及文件系統管理RAIDLV

Objective-C NSFileManager 管理總結

obj mat cto desktop hint ora reat eat fit createFileAtPath //創建文件 NSFileManager *fm = [NSFileManager defaultManager]; N

BZOJ 3289 Mato的管理(莫隊+樹狀數組)

light limit .com print long long blank cmp tar getch 【題目鏈接】 http://www.lydsy.com/JudgeOnline/problem.php?id=3289 【題目大意】   求靜態區間逆序

Linux管理_1

默認 系統 reserve 查找 不同的 指定權限 upper 源文件 inode   在Linux中,全部都是文件,所以文件管理在Linux上格外重要,在我們學習文件管理前,我們先學習幾個關於文件的命令,之後才能更好的學習文件管理。  目錄    pwd命令    cd命

Linux 下的幫助及管理

linux的文件管理1、whatis whatis command 或 man -f command 僅能提供命令基本的介紹。不提具體用法。 基於數據庫的查找,優點:檢索速度快;缺點:缺乏實時性 CentOS6 在文件/var/cache/man/whatis中

管理頁面的制作

name closed size javascrip type jquery content cati tle guanli.php 1 <head> 2 <meta http-equiv="Content-Type" content="text/h