javascript 中从剪贴板抓取部分数据
Grabbing partial data from the clipboard in javascript
我复制了一个 Excel table 大约有一百万行。当我查看系统上的剪贴板时,它似乎包含大约 250MB 的数据。但是,我只需要从中获取样式信息,例如:
这整个数据(远远)不到 1MB 的数据。有没有办法像读取文件或流一样读取剪贴板,这样我就可以这样做,例如:
clipboard.read(1024)
否则,如果我顺子走:
evt.clipboardData.getData('text/html')
然后抓取我要的那段数据拿到数据后,我花了10多秒才搞定!虽然我认为事件应该只需要 0.1 秒左右,但如果我能够以部分方式读取剪贴板数据,就好像它是一个文件一样。
我可以在这里做什么?可以在剪贴板上使用 FileReader
吗?如果可以,那该怎么做?
经过大量研究,这在 Javascript
中是不可能的,不支持使用剪贴板对象进行 stream
操作,因此您必须一次阅读全部内容。
但是,您可以使用 MacOS
(从您的图片推断)本地工具来处理剪贴板数据:pbcopy
和 pbpaste
,它们非常快,数量级比 Javascript
更快,因此您可以将繁重的文本处理委托给他们。
所以,在你复制 250MB 的文本后,你可以将它切片并只读取前 n
个字节(在本例中为 1024),然后用它替换剪贴板的内容,所以现在你就可以了您可以在 Javascript
:
中使用它
pbpaste | cut -b 1-1024 | pbcopy
如果您需要有关每个终端命令的任何文档,您可以 运行 man command_name
。使用这种方法提取剪贴板的前 1024 个字节不到一秒钟。
我用 python
创建的 390MB 示例文本文件测试了这个脚本:
c = 30000000
with open('sample.txt', 'w') as file:
file.writelines('a sample code' for i in range(c))
Clipboard.read
API cited in the comments can return clipboard contents as a list of ClipboardItem
objects, from which you can then obtain a Blob
object, which you can then .slice
to perform partial reads. (The MDN claims 即 Clipboard.read
returns 一个 DataTransfer
对象,但这不符合规范,所以我认为这是陈旧的信息,或者只是错误的。 )
const perm = await navigator.permissions.query({ name: 'clipboard-read' });
switch (perm.state) {
case 'granted':
case 'prompt':
break;
default:
throw new Error("clipboard-read permission not granted");
}
const items = await navigator.clipboard.read();
for (const item of items) {
const blob = await item.getType('text/html');
const first1M = await blob.slice(0, 1048576).arrayBuffer();
/* process first1M */
}
但是,剪贴板 API 目前还远未普及。 Firefox ESR 78.9 没有实现它,而且根据 MDN 的状态,它似乎根本不在 Mozilla 的雷达范围内。 (我还没有尝试过其他浏览器;也许在 Chrome 中它已经可以使用了。)
我复制了一个 Excel table 大约有一百万行。当我查看系统上的剪贴板时,它似乎包含大约 250MB 的数据。但是,我只需要从中获取样式信息,例如:
这整个数据(远远)不到 1MB 的数据。有没有办法像读取文件或流一样读取剪贴板,这样我就可以这样做,例如:
clipboard.read(1024)
否则,如果我顺子走:
evt.clipboardData.getData('text/html')
然后抓取我要的那段数据拿到数据后,我花了10多秒才搞定!虽然我认为事件应该只需要 0.1 秒左右,但如果我能够以部分方式读取剪贴板数据,就好像它是一个文件一样。
我可以在这里做什么?可以在剪贴板上使用 FileReader
吗?如果可以,那该怎么做?
经过大量研究,这在 Javascript
中是不可能的,不支持使用剪贴板对象进行 stream
操作,因此您必须一次阅读全部内容。
但是,您可以使用 MacOS
(从您的图片推断)本地工具来处理剪贴板数据:pbcopy
和 pbpaste
,它们非常快,数量级比 Javascript
更快,因此您可以将繁重的文本处理委托给他们。
所以,在你复制 250MB 的文本后,你可以将它切片并只读取前 n
个字节(在本例中为 1024),然后用它替换剪贴板的内容,所以现在你就可以了您可以在 Javascript
:
pbpaste | cut -b 1-1024 | pbcopy
如果您需要有关每个终端命令的任何文档,您可以 运行 man command_name
。使用这种方法提取剪贴板的前 1024 个字节不到一秒钟。
我用 python
创建的 390MB 示例文本文件测试了这个脚本:
c = 30000000
with open('sample.txt', 'w') as file:
file.writelines('a sample code' for i in range(c))
Clipboard.read
API cited in the comments can return clipboard contents as a list of ClipboardItem
objects, from which you can then obtain a Blob
object, which you can then .slice
to perform partial reads. (The MDN claims 即 Clipboard.read
returns 一个 DataTransfer
对象,但这不符合规范,所以我认为这是陈旧的信息,或者只是错误的。 )
const perm = await navigator.permissions.query({ name: 'clipboard-read' });
switch (perm.state) {
case 'granted':
case 'prompt':
break;
default:
throw new Error("clipboard-read permission not granted");
}
const items = await navigator.clipboard.read();
for (const item of items) {
const blob = await item.getType('text/html');
const first1M = await blob.slice(0, 1048576).arrayBuffer();
/* process first1M */
}
但是,剪贴板 API 目前还远未普及。 Firefox ESR 78.9 没有实现它,而且根据 MDN 的状态,它似乎根本不在 Mozilla 的雷达范围内。 (我还没有尝试过其他浏览器;也许在 Chrome 中它已经可以使用了。)