# 【前端小抄】原生JS讀取、寫出檔案
###### tags: `小抄` `JavaScript`
運用[File](https://developer.mozilla.org/en-US/docs/Web/API/File_API)、[FileList](https://developer.mozilla.org/en-US/docs/Web/API/FileList)和[FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)三個Web API,我們可以透過網頁上的元素獲取使用者選取的檔案。
## 由<input>標籤獲得檔案
假設現在有這個很陽春的網頁:
```htmlembedded
<!DOCTYPE html>
<html>
<body>
<input id = "input" accept = ".xml" type = "file">讀我</input>
<p id = "result"></p>
</body>
</html>
```
因為使用者選取的檔案會被「儲存」在<input>元素中,所以我們要用FileList API存取這些檔案:
```javascript
const Input = document.getElementById('input'); // 選取id為input的HTML標籤
const File = Input.files[0]; // 使用者選取的第一個檔案
```
接著為了讓JavaScript真正「拆開」檔案,我們須借助FileReader API之力:
```javascript
function readFile(file) {
const fileHandler = new FileReader(); // 建構一個名叫fileHandler的FileReader物件
fileHandler.onload = (e) => { // 當檔案讀取完成時(即Load事件發生時)執行
document.getElementById('result').innerHTML = fileHandler.result;
// 顯示檔案
}
fileHandler.readAsText(file,'utf-8'); // 將檔案以UTF-8編碼開啟
}
readFile(File); // 讀取剛接收的檔案
```
## 由Drop事件獲得檔案
Drop事件以及它的兄弟姊妹(Drag、DragEnd、DragEnter、DragLeave、DragOver、DragStart)可以由[HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API)和[DataTransfer API](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer)存取,因此我們把網頁改成這樣:
```htmlembedded
<!DOCTYPE html>
<html>
<body>
<div id = "input" ondrop = "readDroppedFile(event);">丟進來</div>
<p id = "result"></p>
</body>
</html>
```
首先,我們需要先阻止瀏覽器嘗試開啟檔案(你現在可以嘗試拖曳PDF文件到瀏覽器中,瀏覽器預設會將其開啟),所以要加上這段程式碼:
```javascript
function readDroppedFile(e) {
e.preventDefault(); // 防止檔案被瀏覽器開啟
}
```
接著運用DataTransfer API,將程式改寫成這樣:
```javascript
function readDroppedFile(e) {
e.preventDefault(); // 防止檔案被瀏覽器開啟
const dt = e.dataTransfer(); // 建構一個名叫dt的dataTransfer物件
const File = dt.files[0]; // 使用者選取的第一個檔案
readfile(File); // 檔案已經可以餵給前面寫的readFile函數了!
}
```
## 完整小抄
由<input>元素獲得檔案:
```javascript=
function readFile(file) {
const Input = document.getElementById('input');
const File = Input.files[0];
const fileHandler = new FileReader();
fileHandler.onload = (e) => {
return fileHandler.result;
}
fileHandler.readAsText(file,'utf-8');
}
readFile(File);
```
由Drop事件獲得檔案:
```javascript=
function readDroppedFile(e) {
e.preventDefault();
const dt = e.dataTransfer();
const File = dt.files[0];
const fileHandler = new FileReader();
fileHandler.onload = (e) => {
return fileHandler.result;
}
fileHandler.readAsText(file,'utf-8');
}
readDroppedFile(event);
```
## 其他補充