2014-07-18 42 views
18

我正在使用自定义API来允许用户上传文件(希望是任意大小)。如果文件很大,它将被块化,并在多个请求中处理到服务器。什么是HTML5 File.slice方法实际上在做什么?

我在编写使用FileFileReader(HTML5)的代码。一般(从我在网上读)的chunkfied文件传输,人们首先会从他们的文件对象获取数据的BLOB

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的斑点,是否有任何保证在我尝试发送每个请求中的数据之前将执行切片操作。 File对象是否在创建时加载整个文件(当然不是?)。 File.slice寻求参数规定的位置,然后读取?文档没有给我提供如何实现的线索。

回答

21

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

想到Blob(或文件)的最佳方式是指向数据,但不是实际的数据本身。有点像其他语言的文件句柄。

实际上,如果不使用阅读器来读取Blob中的数据,该阅读器会异步读取以避免阻塞UI线程。 ()方法只是返回另一个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,它只是设置边界和(可能)文件指针。

+1

感谢您为我定义File,这更有意义。但是,如果我仍然使用File.Slice(它会返回一个blob),然后尝试使用XMLHttpRequest.send(myBlob)将该Blob发送到服务器,那么如何/何时从该文件检索到数据并将其提供给服务器。或者这只是失败/不发送任何数据? - – Ponml

+0

我更新了我的答案,以提供更多的细节。当我编写我的javascript rsync实用程序时,我深入了解了这些内容:https://github.com/claytongulick/bit-sync –

相关问题