Javascript File 和 FileReader

2023-02-17 10:57 更新

File 對(duì)象繼承自 ?Blob?,并擴(kuò)展了與文件系統(tǒng)相關(guān)的功能。

有兩種方式可以獲取它。

第一種,與 Blob 類似,有一個(gè)構(gòu)造器:

new File(fileParts, fileName, [options])
  • ?fileParts? —— Blob/BufferSource/String 類型值的數(shù)組。
  • ?fileName? —— 文件名字符串。
  • ?options? —— 可選對(duì)象:
    • ?lastModified? —— 最后一次修改的時(shí)間戳(整數(shù)日期)。

第二種,更常見的是,我們從 <input type="file"> 或拖放或其他瀏覽器接口來獲取文件。在這種情況下,file 將從操作系統(tǒng)(OS)獲得 this 信息。

由于 File 是繼承自 Blob 的,所以 File 對(duì)象具有相同的屬性,附加:

  • ?name? —— 文件名,
  • ?lastModified? —— 最后一次修改的時(shí)間戳。

這就是我們從 <input type="file"> 中獲取 File 對(duì)象的方式:

<input type="file" onchange="showFile(this)">

<script>
function showFile(input) {
  let file = input.files[0];

  alert(`File name: ${file.name}`); // 例如 my.png
  alert(`Last modified: ${file.lastModified}`); // 例如 1552830408824
}
</script>

請注意:

輸入(input)可以選擇多個(gè)文件,因此 input.files 是一個(gè)類數(shù)組對(duì)象。這里我們只有一個(gè)文件,所以我們只取 input.files[0]。

FileReader

FileReader 是一個(gè)對(duì)象,其唯一目的是從 Blob(因此也從 File)對(duì)象中讀取數(shù)據(jù)。

它使用事件來傳遞數(shù)據(jù),因?yàn)閺拇疟P讀取數(shù)據(jù)可能比較費(fèi)時(shí)間。

構(gòu)造函數(shù):

let reader = new FileReader(); // 沒有參數(shù)

主要方法:

  • ?readAsArrayBuffer(blob)? —— 將數(shù)據(jù)讀取為二進(jìn)制格式的 ?ArrayBuffer?。
  • ?readAsText(blob, [encoding])? —— 將數(shù)據(jù)讀取為給定編碼(默認(rèn)為 ?utf-8? 編碼)的文本字符串。
  • ?readAsDataURL(blob)? —— 讀取二進(jìn)制數(shù)據(jù),并將其編碼為 base64 的 data url。
  • ?abort()? —— 取消操作。

read* 方法的選擇,取決于我們喜歡哪種格式,以及如何使用數(shù)據(jù)。

  • ?readAsArrayBuffer? —— 用于二進(jìn)制文件,執(zhí)行低級(jí)別的二進(jìn)制操作。對(duì)于諸如切片(slicing)之類的高級(jí)別的操作,?File? 是繼承自 ?Blob? 的,所以我們可以直接調(diào)用它們,而無需讀取。
  • ?readAsText? —— 用于文本文件,當(dāng)我們想要獲取字符串時(shí)。
  • ?readAsDataURL? —— 當(dāng)我們想在 ?src? 中使用此數(shù)據(jù),并將其用于 ?img? 或其他標(biāo)簽時(shí)。正如我們在 Blob 一章中所講的,還有一種用于此的讀取文件的替代方案:?URL.createObjectURL(file)?。

讀取過程中,有以下事件:

  • ?loadstart? —— 開始加載。
  • ?progress? —— 在讀取過程中出現(xiàn)。
  • ?load? —— 讀取完成,沒有 error。
  • ?abort? —— 調(diào)用了 ?abort()?。
  • ?error? —— 出現(xiàn) error。
  • ?loadend? —— 讀取完成,無論成功還是失敗。

讀取完成后,我們可以通過以下方式訪問讀取結(jié)果:

  • ?reader.result? 是結(jié)果(如果成功)
  • ?reader.error? 是 error(如果失?。?/li>

使用最廣泛的事件無疑是 load 和 error。

這是一個(gè)讀取文件的示例:

<input type="file" onchange="readFile(this)">

<script>
function readFile(input) {
  let file = input.files[0];

  let reader = new FileReader();

  reader.readAsText(file);

  reader.onload = function() {
    console.log(reader.result);
  };

  reader.onerror = function() {
    console.log(reader.error);
  };

}
</script>

?FileReader? 用于 blob

正如我們在 Blob 一章中所提到的,FileReader 不僅可讀取文件,還可讀取任何 blob。

我們可以使用它將 blob 轉(zhuǎn)換為其他格式:

  • ?readAsArrayBuffer(blob)? —— 轉(zhuǎn)換為 ?ArrayBuffer?,
  • ?readAsText(blob, [encoding])? —— 轉(zhuǎn)換為字符串(?TextDecoder? 的一個(gè)替代方案),
  • ?readAsDataURL(blob)? —— 轉(zhuǎn)換為 base64 的 data url。

在 Web Workers 中可以使用 ?FileReaderSync?

對(duì)于 Web Worker,還有一種同步的 FileReader 變體,稱為 FileReaderSync

它的讀取方法 read* 不會(huì)生成事件,但是會(huì)像常規(guī)函數(shù)那樣返回一個(gè)結(jié)果。

不過,這僅在 Web Worker 中可用,因?yàn)樵谧x取文件的時(shí)候,同步調(diào)用會(huì)有延遲,而在 Web Worker 中,這種延遲并不是很重要。它不會(huì)影響頁面。

總結(jié)

File 對(duì)象繼承自 Blob。

除了 Blob 方法和屬性外,File 對(duì)象還有 name 和 lastModified 屬性,以及從文件系統(tǒng)讀取的內(nèi)部功能。我們通常從用戶輸入如 <input> 或拖放事件來獲取 File 對(duì)象。

FileReader 對(duì)象可以從文件或 blob 中讀取數(shù)據(jù),可以讀取為以下三種格式:

  • 字符串(?readAsText?)。
  • ?ArrayBuffer?(?readAsArrayBuffer?)。
  • data url,base-64 編碼(?readAsDataURL?)。

但是,在很多情況下,我們不必讀取文件內(nèi)容。就像我們處理 blob 一樣,我們可以使用 URL.createObjectURL(file) 創(chuàng)建一個(gè)短的 url,并將其賦給 <a> 或 <img>。這樣,文件便可以下載文件或者將其呈現(xiàn)為圖像,作為 canvas 等的一部分。

而且,如果我們要通過網(wǎng)絡(luò)發(fā)送一個(gè) File,那也很容易:像 XMLHttpRequest 或 fetch 等網(wǎng)絡(luò) API 本身就接受 File 對(duì)象。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)