什么是HTML5 File.slice方法实际上在做什么?

时间:2014-07-18 20:42:52

标签: javascript html5 algorithm file-upload chunking

我正在使用自定义API来允许用户上传文件(希望是任意大小)。如果文件很大,它将被chunkfied,并在对服务器的多个请求中处理。

根据网上的许多示例,我编写的代码使用FileFileReader(HTML5)。一般来说(从我在网上看到的)对于一个chunkfied文件传输,人们将首先从他们的文件对象中获取一大块数据

var file = $('input[type=file]')[0].files[0];
var blob = file.slice(start,end)

然后使用FileReader阅读blob readAsArrayBuffer(blob)readAsBinaryString(blob)

最后在FileReader.onload(e)方法中,将数据发送到服务器。对文件中的所有块重复此过程。

我的问题是

为什么我需要使用FileReader?如果我不使用它,并且只是发送带有File.slice的blob,那么在我尝试在每个请求中发送数据之前,是否可以保证切片操作将完成。 File对象在创建时是否加载整个文件(当然不是?)。 File.slice是否寻求参数规定的位置,然后读取信息?文档没有给我一个关于它如何实现的线索。

1 个答案:

答案 0 :(得分:28)

要记住的重要一点是File继承自Blob,File实际上没有slice方法,它从Blob获取此方法。文件只添加了几个元数据属性。

考虑Blob(或文件)的最佳方法是作为数据的指针,而不是实际的数据本身。有点像其他语言的文件句柄。

如果不使用读取器,实际上无法访问Blob中的数据,读取器会异步读取以避免阻止UI线程。

Blob slice()方法只返回另一个Blob,但同样,这不是数据,它只是指向原始Blob中的一系列数据的指针,有点像指向视图的有界指针。要实际从切片的Blob中获取字节,您仍然需要使用阅读器。在切片斑点的情况下,您的读者是有限的。

这实际上只是为了方便您在代码中不必携带一堆相对和绝对的偏移量,您可以获得有限的数据视图并使用读者,就好像您是从字节0读取。

对于XMLHttpRequest(假设浏览器支持更新的接口),数据将在发送时进行流式传输,并受blob边界的约束。基本上,如果您将文件指针发送到流方法(这基本上是在幕后的内容),它将以您想象的方式工作。 https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data#Sending_binary_data

基本上,它是一个懒惰的读者。如果blob已经从文件系统加载/读取,或者是在内存中创建的,那么它就是要使用它。当您使用文件时,它将被延迟加载并异步流出主线程。

这里的基本逻辑是浏览器开发人员从不希望读取同步发生,因为它可能会阻塞主线程,因此所有API都是围绕该核心理念设计的。注意Blob.slice()是如何同步的 - 这就是你怎么知道它实际上并没有做任何IO,它只是设置边界和(可能)文件指针。