javascript - 输入文件大小和内容不会在 macOS 上更新

标签 javascript html filereader

我写了一个基于网络的小工具,它使用文件输入来读取不断变化的文件。用户手动选择它(一次!)并且 JavaScript 跟踪它何时被更改(上次文件修改时间和文件大小)。如果它已经改变,它会再次读取文件内容。

这在 Windows 上的所有浏览器中都可以正常工作。但在 macOS 上(在 Safari 10.1.2 和 Firefox 51.0.1 中测试)似乎只有最后修改时间被更新。文件大小没有更新,而且似乎也无法再读取文件内容。所以我无法在 macOS 上的浏览​​器中跟踪文件更改。

但是为什么?这是 macOS 中的安全限制吗?

请使用以下代码段进行测试。选择一个文件(例如文本文件),查看上次修改的时间戳和文件大小,然后更改文件并再次查看,如果大小已更改。在 macOS 上,文件大小不会改变。

请不要使用 jQuery。

window.addEventListener('load', function() {
  window.setInterval(function() {
    var logFile = document.querySelector('#file').files[0];
    if (logFile) {
      document.querySelector('#info').innerHTML = '<br/>' +
        (new Date()).toString() + '<br/>Last modified: ' +
        logFile.lastModified +
        '<br/>Size: ' +
        logFile.size;
    }
  }, 1000);
});
#info {
  font-family: Courier;
  font-size: 0.9em;
}
<!DOCTYPE html>
<input type="file" id="file" />
<p id="info"></p>

最佳答案

我不认为这是一种安全措施,而只是一种性能措施。
一旦他们获得了文件元数据信息,他们将不再请求它,因为进一步获得 => 减少对用户磁盘的访问。
老实说,我什至有点惊讶在 Windows 上他们每次都请求这些元数据。

要解决这个问题,不是一件容易的事,我会重新考虑对此的需求,以及消息传递是否不能在另一个级别完成(例如,从确实修改文件的进程)。

事实上,Firefox 和 Safari 在这种情况下的表现并不相同:

  • Safari 似乎会在您从输入中选择文件后立即创建一个指向该文件的 blobURI,并在您稍后尝试访问它时始终使用它(例如从 FileReader)。这里真正的问题是我们无法在磁盘上获取新版本,因为无论出于何种原因,这个 blobURI 似乎并不是磁盘的真正指针......但是如果我们只想检测文件更改,这对我们有好处,因为我们只需要检查 FileReader.onerror 事件,即使使用 File.slice(0,1 )(即最少的 I/O)。

  • 另一方面,如果缓存的元数据的大小与已读取的元数据的大小不匹配,Firefox 将触发 FileReader 的错误。这意味着您必须在每次检查时读取整个文件,并且,如果没有发生错误,请仔细检查数据是否实际上相同......但是,在这个浏览器中,您仍然可以使用 blobURI 从 AJAX 获取磁盘上的实际文件,以获得最新版本。

关于javascript - 输入文件大小和内容不会在 macOS 上更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50370493/

相关文章:

javascript - 可拖动到元素后面

javascript - 相当于python中的date.utc

javascript - 如何发送推送通知 chrome android 移动设备 pwa

java - 解析Java中的目录结构

javascript - 如何在另一个jquery文件中调用jquery方法

javascript - YAHOO.lang 的 jQuery 版本(isUndefined、isNull、isString 等)

javascript - 如何使搜索表单背景颜色同时悬停在输入提交和输入文本上

javascript - 无法让 CSS3 转换在 IE 10/11 中工作

Java将文本拆分为数组然后添加值

angular - 如何等待 'for loop next iteration' 直到 FileReader.onload 结果获得