好的,我有一个程序可以将一些特定数据输出到制表符分隔的变量文件中。
我一直在使用Excel打开并查看文件内容,但是我发现excel坚持要锁定它打开的每个文件都非常烦人,因为如果我在Excel中打开文件我的程序会崩溃...但我会非常喜欢在每次运行程序后整齐更新的数据,所以我不必一直关闭并重新打开文件。
所以,我决定用最简单的方法来解析文件并将其显示在html表中,就是这样。我立刻把东西撞到了一起。现在,如果我将文件保留在显示状态,我的程序不会崩溃,但是,它仍然不会更新......我每次都必须打开新生成的文件。
所以,我想知道是否有一种机制可以通过其他进程以某种方式通知我的Javascript对文件的更改?我知道这不太可能,但我想避免简单地轮询文件,原因很明显。
我对JS非常熟悉,但HTML5和新API对我来说都是新手。
答案 0 :(得分:9)
我不相信File API有任何更改文件的事件,只是进度事件等。
您可以使用投票。请记住File
的{{3}},然后当您的轮询功能触发时,为输入获取一个新的File
实例,并查看lastModifiedDate
是否已更改。
这适用于Chrome,例如:lastModifiedDate
| Live Copy
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Watch for a file change</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
</style>
</head>
<body>
<input type='file' id='filename'>
<input type='button' id='btnStart' value='Start'>
<script type='text/javascript'>
(function() {
var input;
var lastMod;
document.getElementById('btnStart').onclick = function() {
startWatching();
};
function startWatching() {
var file;
if (typeof window.FileReader !== 'function') {
display("The file API isn't supported on this browser yet.");
return;
}
input = document.getElementById('filename');
if (!input) {
display("Um, couldn't find the filename element.");
}
else if (!input.files) {
display("This browser doesn't seem to support the `files` property of file inputs.");
}
else if (!input.files[0]) {
display("Please select a file before clicking 'Show Size'");
}
else {
file = input.files[0];
lastMod = file.lastModifiedDate;
display("Last modified date: " + lastMod);
display("Change the file");
setInterval(tick, 250);
}
}
function tick() {
var file = input.files && input.files[0];
if (file && lastMod && file.lastModifiedDate.getTime() !== lastMod.getTime()) {
lastMod = file.lastModifiedDate;
display("File changed: " + lastMod);
}
}
function display(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
})();
</script>
</body>
</html>
答案 1 :(得分:3)
而T.J.克劳德的答案是正确的,Chrome的实施似乎打破了规范。
每个Blob必须具有内部快照状态,如果存在任何此类底层存储,则必须将其初始设置为基础存储的状态,并且必须通过结构化克隆进行保留。可以为文件找到快照状态的进一步规范性定义。
选择文件时,输入会显示该点内容的快照。磁盘上的本地更改不会更新快照。
答案 2 :(得分:2)
有两个解决方案,<input type="file">
不是其中之一。根据规范,它会创建文件的“快照”。
此api是实验性的,要求在眨眼时启用标志(又名Chrome浏览器)。这样做的目的是获得文件句柄,然后在需要文件时调用异步“ getFile”函数来检索实际文件。
此功能是一项“强大功能”,要求您的网站安全,并且不能在沙盒iframe中使用
因此,这里未经测试就是一些“黑暗中的代码”:
// triggerd on click
async function pickFile () {
// const handle = showOpenFilePicker() // chrome 85
const handle = await chooseFileSystemEntries() // deprecated (split up to 3 fns)
let lastModificationTime = new Date(0)
async function compare (meta) {
const file = await handle.getFile()
if (file.lastModifiedDate > lastModificationTime) {
lastModificationTime = file.lastModifiedDate
console.log(await file.text())
}
}
setInterval(compare, 1000)
}
类似于本机文件系统,您还可以检索文件句柄并执行相同的操作,但是此功能在当今的浏览器中有效。但是此代码段在stackoverflow中不起作用,因为它使用了一些沙箱,使其变得不兼容,所以这里是fiddle,几乎没有注释
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 = new Date(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)
}