检查本地文件是否改变

Check if local file has changed

我有一个网络应用程序,用户可以使用 html5 FileReader API select 本地文件作为输入。有什么方法可以检查文件是否已更改,是否适用于现代浏览器?

从历史上看,这在某些浏览器中是可能的,方法是轮询文件对象并比较 File.lastModifiedDate(已弃用)或 File.lastModified 属性,如本 QA 中所述:Check if file has changed using HTML5 File API.然而,规范说 lastModifiedDate 和其他文件数据应该是文件的快照,就像用户第一次 select 编辑它时的样子,所以这不应该工作(而且看起来像最近的版本大多数浏览器现在确实遵循规范,因此无法使用此 hack)。

我希望能够通过读取文件来检查更改。这种方法可行,但是一旦磁盘上的文件发生更改,Chrome 和 Firefox 就会抛出一个错误提示 DOMException: The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired. 有什么办法解决这个问题吗?

这是我试过的:

let oldText

setInterval(function () {
  const fileObj = document.getElementById('myFileInput').files[0]
  const reader = new FileReader()
  reader.onload = evt => {
      const text = evt.target.result
      if (text !== oldText) {
        console.log("The file has changed!")
        oldText = text
      }
    }
    reader.readAsText(fileObj)
}, 1000)

...或更简单:

const fileObj = document.getElementById('myFileInput').files[0]
const reader = new FileReader()
reader.readAsText(fileObj)  // works
// now lets edit the file and try again
reader.readAsText(fileObj)  // fails

reader.readAsText() 按预期工作,直到文件被更改,当它抛出上述错误时。我想这是某种安全措施,但我不完全理解它试图保护用户免受什么影响。我可以做什么?

这将再次成为可能 if/when Native File System API is implemented in browsers. It will be partially enabled Google Chrome 85,计划于 2020 年 10 月发布。

与 FileReader API 不同,它需要明确的用户交互,因此您可以这样做:

myFileInput.addEventListener('change', async (e) => {
  const fh = await window.chooseFileSystemEntries()
  // fh is now a FileSystemFileHandle object
  // Use fh.getFile() to get a File object
})