HTML文件输入 - 一旦选定就锁定文件

时间:2017-09-07 09:06:10

标签: javascript html file-locking

浏览器在被<input type="file" />选中后是否有办法“锁定”文件?现在我可以选择一个文件,用JavaScript开始一些操作,同时我可以从我的磁盘中删除它,这会导致JavaScript代码出错。

编辑我的目标是确保在使用JavaScript处理文件时无法删除该文件。

2 个答案:

答案 0 :(得分:3)

没有办法。仅仅因为JS是客户端语言,即使在服务器端,这也是不可能的,因为您无法与用户计算机进行交互。要做到这一点,你需要你的桌面应用程序,例如将文件复制并锁定它。

如果要实现这一点,则必须在浏览器中实现。

编辑补充:

如果您考虑一下为什么这已经没有在浏览器中实现,也许是因为如果您在上传文件时会发生什么?保持锁定?

答案 1 :(得分:0)

:您可以在内存中创建副本,并使用此副本代替用户磁盘上的文件。
您必须首先阅读其内容并从那里创建一个新的文件/ Blob:

let theFile = null;
inp.onchange = async function(e) {
  theFile = await saveBlob(inp.files[0]);
  btn.disabled = false;
  inp.disabled = true;
}
btn.onclick = e => {
  console.log(theFile);
  let reader = new FileReader();
  // to prove it's really still there
  reader.onload = e => console.log(new Uint8Array(reader.result));
  reader.onerror = e => console.log(e);
  reader.readAsArrayBuffer(theFile.slice(0, 4));
}

function saveBlob(blob) {
  let reader = new FileReader();
  return new Promise((res, rej) => {
  reader.onload = e => {
    if (blob instanceof File) { 
    // tries to keep it as a File, but beware some implementations still have bugs
      res( new File([reader.result], blob.name, {type: blob.type}) );
    } else {
      res( new Blob([reader.result], {type: blob.type}) );
    }
  };
  reader.onerror = rej; // already removed ???
  reader.readAsArrayBuffer(blob);
  });
}
<input type="file" id="inp">
<button id="btn" disabled>I did remove it from disk</button>

另一种方法是将其存储在indexedDB中。

然后,您可以使用此副本,并确保它将保留在内存中,无论用户使用原始文件做什么。

如果您需要保留的时间超过文档的生命周期,则可以创建一个blobURI(URL.createObjectURL(theFile)),您可以将其存储在localStorage中,并使用fetch(blobURI).then(r=>r.blob());进行重新加载或重定向检索。
如果你需要它存活更长时间(硬刷新会杀死blobURI的引用),那么使用indexedDB。

修改以回复question's edit

显然,你无法在用户磁盘上更改文件的权限,但是你不需要这样做,因为你可以获得它的副本。