@[toc]
需求
在浏览器中打开本地文件夹并获取指定文件夹下的内容 在早期的时候呢,这些API确实是没有的,也就是根本不允许 在浏览器中读取本地文件夹里的信息,但是后期出现的 File API,逐渐可以实现该功能,它是允许用户授权给这个网站,去读取到它的一些本地信息
分析
针对以上问题,我们做几个实现步骤:
1. 如何弹出文件夹选择框
比如说网页上有一个按钮,点击后需要弹出一个文件夹的选择框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="shortcut icon" type="image/x-icon" href="/tit_logo.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>111</title>
</head>
<body>
<div id="app">
<button>打开文件夹</button>
</div>
<script>
const btn = document.querySelector('button');
btn.onclick = function () {
// window.open
showDirectoryPicker()
}
</script>
</body>
</html>
2. 如何获取文件夹中的内容
-
使用 showDirectoryPicker() 方法进行读取,该方法返回的是一个句柄,打印结果如下,返回结果很简单,只有一个文件类型和文件夹的名
const btn = document.querySelector('button'); btn.onclick = async function () { const handle = await showDirectoryPicker() console.log(handle) }
-
获取该文件夹下的内容
const btn = document.querySelector('button'); btn.onclick = async function () { const handle = await showDirectoryPicker() await processHandle(handle)// 文件的操作都是异步的因此这里用异步进行处理 } async function processHandle (handle) { if (handle.kind === 'file') { return } // entries:异步迭代器 const entries = await handle.entries() for await (const entrie of entries) { console.log(entrie); } }
-
获取到文件夹下的所有内容,就需要写一个递归方法
<script> const btn = document.querySelector('button'); btn.onclick = async function () { const handle = await showDirectoryPicker() await processHandle(handle)// 文件的操作都是异步的因此这里用异步进行处理 console.log(handle); } async function processHandle (handle) { if (handle.kind === 'file') { return } // entries:异步迭代器 const entries = await handle.values() handle.children = [] for await (const subHandle of entries) { handle.children.push(subHandle) await processHandle(subHandle) } } </script>
3. 如何读取文件内容
既然可以拿到该类型为 File 的文件,那么接下来就是读取文件的内容了
const file = await fileHandle.getFile()
const reader = new FileReader()
reader.onload = e => {
console.log(e.target.result);
}
reader.readAsText(file)
我们看到和文件中的内容没有区别
4. 总体代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="shortcut icon" type="image/x-icon" href="/tit_logo.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>111</title>
</head>
<body>
<div id="app">
<button>打开文件夹</button>
</div>
<script>
const btn = document.querySelector('button');
btn.onclick = async function () {
const handle = await showDirectoryPicker()
await processHandle(handle)// 文件的操作都是异步的因此这里用异步进行处理
const fileHandle = handle.children[0]
const file = await fileHandle.getFile()
const reader = new FileReader()
reader.onload = e => {
console.log(e.target.result);
}
reader.readAsText(file)
}
async function processHandle (handle) {
if (handle.kind === 'file') {
return
}
// entries:异步迭代器
const entries = await handle.values()
handle.children = []
for await (const subHandle of entries) {
handle.children.push(subHandle)
await processHandle(subHandle)
}
}
</script>
</body>
</html>