这个问题有两种解决方案,而且<input type="file">
不是其中之一。根据规范,它会创建文件的“快照”。
本机文件系统
此api是实验性的,需要在闪烁时启用标志(又名 chromium 浏览器)。这个想法是你得到一个文件句柄,当你需要文件时,你调用异步“getFile”函数来检索实际文件。
此功能是一项“强大功能”,需要您的网站安全,并且无法在沙盒 iframe 中使用。
所以这里没有测试是一些“黑暗中的代码”:
// triggerd on click
async function pickFile () {
const handle = showOpenFilePicker()
let lastModificationTime = 0
async function compare () {
const file = await handle.getFile()
if (file.lastModified > lastModificationTime) {
lastModificationTime = +file.lastModified
console.log(await file.text())
}
}
setInterval(compare, 1000)
}
通过拖放获取条目
与本机文件系统类似,您也可以检索文件句柄并执行相同的操作,但此功能适用于当今的所有浏览器。但是这个代码片段在 stackoverflow 中不起作用,因为它使用了一些沙盒使其不兼容,所以这里有一些评论
function drop(event) {
event.stopPropagation();
event.preventDefault();
// get the file as an fileEntry (aka file handle)
const fileEntry = event.dataTransfer.items[0].webkitGetAsEntry()
let lastModificationTime = 0
async function read (file) {
// use the new async read method on blobs.
console.log(await file.text())
}
function compare (meta) {
if (meta.modificationTime > lastModificationTime) {
lastModificationTime = meta.modificationTime
fileEntry.file(read)
}
}
setInterval(fileEntry.getMetadata.bind(fileEntry, compare), 1000)
}
编辑:现在还有一种方法可以将拖放文件作为 FileSystemFileHandle 更好地使用
elem.addEventListener('dragover', evt => {
// Prevent navigation.
evt.preventDefault()
})
elem.addEventListener('drop', async evt => {
// Prevent navigation.
evt.preventDefault()
// Process all of the items.
for (const item of evt.dataTransfer.items) {
// kind will be 'file' for file/directory entries.
if (item.kind === 'file') {
const entry = await item.getAsFileSystemHandle();
if (entry.kind === 'file') {
// use same solution as the first Native File System solution
}
}
}
})