JavaScript File 物件

admin發表於2019-01-02

File 翻譯成中文具有 "檔案" 的意思,恰如其名,File 物件用於表示一個檔案。

繼承自 Blob ,並對其進行擴充套件,可以說 File 物件是一個特殊 Blob 物件。

結合 File 物件可以實現 web 端對檔案的讀取、上傳或者下載等操作。

一.歷史需求:

HTML5 之前,web 端對本地檔案的操作侷限性很大。

僅能利用 <input type="file"> , 但是 web 端也不能讀取檔案的內容。

甚至 JavaScript 都無法讀取檔案的路徑,具體參閱 路徑 fakepath 關鍵字 一章節。

二.HTML5 改進:

為了解決之前存在的問題,HTML5 進行了大幅度的改進。

首先,<input type="file"> 功能得到了提升:

(1).通過 multiple 屬性使其能夠一次性選中多個檔案。

(2).通過 accept 屬性控制可以選中檔案的 MIME 型別。

通過 <input type="file"> 元素物件的 files 屬性返回一個存放選中檔案物件的 FileList 集合。

三.建立 File 物件:

獲取 File 物件方式有多種,下面對主要方式進行一下概述。

1.建構函式方式:

通過建構函式 File 可以建立一個 File 物件。

語法結構:

[JavaScript] 純文字檢視 複製程式碼
new File(array, name [, options])

引數解析:

(1).array:必需,一個陣列,用來儲存 File 物件的內容,陣列元素可以是二進位制物件或者字串。

(2).name:必需,規定檔案的名字。

(3).options:可選,一個配置物件,用來設定 File 物件內容的相關特徵,具有兩個屬性:         

            type:字串,規定 File 內容的 MIME 型別。

            lastModified:一個時間戳,規定 File 檔案上次修改的時間,預設值是 Date.now()。

下面通過建構函式建立一個 File 物件,程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
let file = new File(['螞蟻部落前端'],'ant.txt',{
  type: 'text/plain',
});

程式碼分析如下:

(1).第一個陣列規定file檔案的內容,是一個字串。

(2).檔案的名稱為ant.txt。

(3).檔案內容是純文字格式。

2.<input type="file">:

利用此元素物件的 files 屬性可以獲取存放File 檔案物件的 FileList 集合。

然後利用索引可以取出每一個 File 檔案物件,下文程式碼中有涉及。

3.DataTransfer 拖拽:

通過拖拽同樣可以獲取 File 物件,不做具體介紹。

具體參閱 DataTransfer.files 屬性一章節。

四.物件屬性與方法:

File 物件具有五個屬性和一個方法,具體如下:

(1).name:字串,表示檔名稱。

(2).size:數字,表示檔案的大小,規定的是檔案位元組的數目。

(3).type:字串,表示檔案的MIME型別,如果無法辨別型別,則為空字串,只讀屬性。

(4).lastModified:數字,表示檔案的上次被修改的時間,時間戳。

(5).lastModifiedDate:字串,檔案的上次修改時間。

(6).slice():可以在原有 File 物件基礎上生成一個新的File物件,通過此方法可以實現檔案分段上傳。

特別說明:此物件繼承自 Blob 物件,size、type 和 slice() 是繼承自 Blob,剩餘屬性是自己擴充套件。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<meta name="author" content="https://www.softwhy.com/" /> 
<title>螞蟻部落</title>
<script>
window.onload=function(){
  let ofile=document.getElementById("file");
  file.onchange = function () {
    console.log(this.files[0]);
  }
}
</script>
</head> 
<body>
<input type="file" id="file" multiple>
</body>
</html>

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/202003/31/123107qqh00m5hdpphuzmy.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

程式碼分析如下:

(1).通過控制元件上傳的檔案都會生成一個 File 物件,這些物件存放在 FileList 集合中。

(2).為控制元件註冊 change 事件處理函式,控制元件選中檔案後會觸發 change 事件,進而執行事件處理函式。

(3).控制元件物件的 files 屬性返回一個 FileList 集合,其中的元素是 File 物件。

(4).最後可以列印出 File 物件的相關屬性。

slice() 方法具體用法本文不再介紹,具體參閱 File slice() 一章節。

利用此方法可以檔案分段上傳功能,這對於上傳大檔案非常重要,簡單程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
var h = {
  init: function () {
    var _this = this;
   
    document.getElementById("File").onchange = _this.fileHandler;
    document.getElementById("Abort").onclick = _this.abortHandler;
   
    _this.status = document.getElementById("Status");
    _this.progress = document.getElementById("Progress");
    _this.percent = document.getElementById("Percent");
   
    _this.loaded = 0;
    //每次讀取1M  
    _this.step = 1024 * 1024;
    _this.times = 0;
  },
  fileHandler: function (e) {
    var _this = h;
    _this.file = this.files[0];
    _this.reader = new FileReader();
   
    _this.total = _this.file.size;
   
    _this.reader.onloadstart = _this.onLoadStart;
    _this.reader.onprogress = _this.onProgress;
    _this.reader.onabort = _this.onAbort;
    _this.reader.onerror = _this.onerror;
    _this.reader.onload = _this.onLoad;
    _this.reader.onloadend = _this.onLoadEnd;
    //讀取第一塊  
    _this.readBlob(0);
  },
     
  readBlob: function (start) {
    var _this = h;
   
    var blob,
        file = _this.file;
   
    _this.times += 1;
   
    blob = file.slice(start, start + _this.step + 1);
    _this.reader.readAsText(blob);
  },
   
  onLoadStart: function () {
    var _this = h;
  },
   
  onProgress: function (e) {
    var _this = h;
    _this.loaded += e.loaded;
    //更新進度條  
    _this.progress.value = (_this.loaded / _this.total) * 100;
  },
   
  onAbort: function () {
    var _this = h;
  },
  onError: function () {
    var _this = h;
  },
   
  onLoad: function () {
    var _this = h;
   
    if (_this.loaded < _this.total) {
      _this.readBlob(_this.loaded);
    } else {
      _this.loaded = _this.total;
    }
  },
   
  onLoadEnd: function () {
    var _this = h;
  },
     
  abortHandler: function () {
    var _this = h;
   
    if (_this.reader) {
      _this.reader.abort();
    }
  }
};
   
window.onload = function () {
  h.init();
}
</script>
</head>
<body>
<form>
  <fieldset>
    <legend>分度讀取檔案:</legend>
    <input type="file" id="File" />
    <input type="button" value="中斷" id="Abort" />
    <p>
      <label>讀取進度:</label>
      <progress id="Progress" value="0" max="100"></progress>
    </p>
    <p id="Status"></p>
  </fieldset>
</form>  
</body>
</html>

演示了利用 slice() 方法分段上傳效果,並且帶有上傳進度條。

上述程式碼用到了 FileReader 物件讀取檔案,具體參閱 FileReader教程 板塊。

相關文章