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

Pon*_*nml 26 javascript algorithm html5 file-upload chunking

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

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

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

然后使用a FileReader来读取blob readAsArrayBuffer(blob)readAsBinaryString(blob)

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

我的问题是

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

Cla*_*ick 31

要记住的重要一点是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,它只是设置边界和(可能)文件指针.

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