我正在使用一个自定义API来允许用户上传文件(希望是任意大小)。如果文件太大,它将被分块,并在对服务器的多个请求中进行处理。
我正在编写使用File
和FileReader
(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
发送blobs,是否可以保证切片操作将在我尝试发送每个请求中的数据之前完成。在创建文件时,File
对象会加载整个文件吗(当然不会?)File.slice
是否查找到参数指定的位置,然后读取其中的信息?文档并没有给我提供关于它是如何实现的线索。
发布于 2014-07-19 05:59:11
要记住的重要一点是,File继承自Blob,File实际上没有slice方法,它从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已经从文件系统加载/读取,或者是在内存中创建的,它将直接使用它。但是,当你使用一个文件时,它会被延迟加载并异步地流出主线程。
这里的基本逻辑是,浏览器开发人员永远不会希望读取同步发生,因为它可能会阻塞主线程,因此所有的API都是围绕这一核心原理设计的。注意Blob.slice()是如何同步的-这就是你如何知道它实际上并没有做任何IO,它只是设置了界限和(可能的)文件指针。
https://stackoverflow.com/questions/24833487
复制相似问题