JavaScript File 物件

admin發表於2019-01-02

HTML5之前,檔案應用頻繁,比如通過<input file>控制元件上傳檔案,但是沒有相應JavaScript介面對其操作。

當前,HTML5新增File物件,在一定程度上實現對上傳檔案較為便利的操作。

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

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

關於Blob物件內容可以參閱JavaScript Blob 物件一章節。

一.File物件應用場景:    

如果暫時對File物件不熟悉,那麼大家一定對<input file>元素非常熟悉。

利用此控制元件,使用者可以一次上傳一個或者多個檔案,當檔案被選中以後,會生成衣集合。

集合中的每一個元素就是一個File物件。

特別說明:預設<input file>一次只能上傳一個檔案,需要新增multiple屬性。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<meta name="author" content="http://www.softwhy.com/" /> 
<title>螞蟻部落</title>
</head> 
<body>
<input type="file" multiple>
</body>
</html>
   

上述控制元件可以一次性選擇多個檔案,大家可以去掉multiple進行一下對比。

二.建立File物件:    

通過建構函式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).檔案內容是純文字格式。

三.物件的屬性和方法:    

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

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

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

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

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

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

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

程式碼例項如下:程式碼分析如下:

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

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

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

四.物件的屬性和方法:    

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

(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="http://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/201901/02/115337a58tn5cn6zt6ywnz.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}
   

程式碼分析如下:

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

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

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

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

關於slice方法的具體用法本文不再介紹,具體參閱JavaScript Blob 物件一章節。

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

[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方法分段上傳效果,並且帶有上傳進度條。

程式碼中的相關知識,都可以在螞蟻部落教程查閱到,本文不再對其進行分析,如有疑問可以在文章底部留言。

相關文章