【问题标题】:What is HTML5 File.slice method actually doing?HTML5 File.slice 方法实际上在做什么?
【发布时间】:2014-09-10 02:13:12
【问题描述】:

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

根据网上的许多示例,我正在编写使用 FileFileReader (HTML5) 的代码。一般来说(根据我在网上阅读的内容)对于分块文件传输,人们首先会从他们的文件对象中获取一团数据

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是不是先寻找到参数规定的位置,然后把信息读进去?文档没有给我关于它是如何实现的线索。

【问题讨论】:

    标签: javascript html algorithm file-upload chunking


    【解决方案1】:

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

    理解 Blob(或文件)的最佳方式是将其视为指向数据的指针,而不是实际数据本身。有点像其他语言的文件句柄。

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

    Blob slice() 方法只是返回另一个 Blob,但同样,这不是数据,它只是指向原始 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 已经从文件系统加载/读取,或者是在内存中创建的,它只会使用它。但是,当您使用 File 时,它​​会延迟加载并从主线程异步流式传输。

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

    【讨论】:

    • 感谢您为我定义文件,这更有意义。但是,如果我仍然使用 File.Slice(它返回一个 blob),然后尝试使用 XMLHttpRequest.send(myBlob) 将该 blob 发送到服务器,则如何/何时从文件中检索数据并提供给服务器.或者这会失败/不发送任何数据? ——
    • 我更新了答案以提供更多细节。当我编写我的 javascript rsync 实用程序时,我非常深入地研究了这些东西:github.com/claytongulick/bit-sync
    猜你喜欢
    • 2015-05-27
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 2013-06-02
    • 2020-11-21
    相关资源
    最近更新 更多