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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24833487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 03:25:03  来源:igfitidea点击:

What is HTML5 File.slice method actually doing?

javascripthtmlalgorithmfile-uploadchunking

提问by Ponml

I'm working with a custom API to allow a user to upload a file (of, hopefully, arbitrary size). If the file is to large, it will be chunkfied, and handled in multiple requests to the server.

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

I'm writing code that uses Fileand FileReader(HTML5) as per many examples from online. In general (from what I read online) for a chunkfied file transfer, people will first get a blob of data from their file object

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

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

Then use a FileReaderto read the blob readAsArrayBuffer(blob)or readAsBinaryString(blob)

然后使用 aFileReader读取 blobreadAsArrayBuffer(blob)readAsBinaryString(blob)

And finally in FileReader.onload(e)method, send the data to the server. Repeat this process for all the chunks in the file.

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

My questions are

我的问题是

Why do I need to use a FileReader? If I don't use it, and simply send blobs with File.slice, is there any guarantee that the slicing operation will be done before I try to send the data in each request. Does the Fileobject load the entire file when it's created (surely not?). Does File.sliceseek to the position stipulated by the parameters, and then read the information in? The documentation doesn't give me an clues on how it's implemented.

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

回答by Clayton Gulick

The important thing to keep in mind is that File inherits from Blob, File doesn't actually have a slice method, it gets this method from Blob. File just adds a couple metadata attributes.

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

The best way to think of a Blob (or File) is as a pointer to data, but not the actual data itself. Sort of like a file handle in other languages.

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

You can't actually get to the data in a Blob without using a reader, which reads asynchronously to avoid blocking the UI thread.

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

The Blob slice() method just returns another Blob, but again, this isn't data, it's just a pointer to a range of data within the original Blob, sort of like a bounded pointer to a view. To actually get the bytes out of the sliced Blob, you still need to use a reader. In the case of a sliced blob, your reader is bounded.

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

This is really just intended as a convenience so that you don't have to carry a bunch of relative and absolute offsets around in your code, you can just get a bounded view of the data and use the reader as if you were reading from byte 0.

这实际上只是为了方便起见,这样您就不必在代码中携带一堆相对和绝对偏移量,您只需获得数据的有界视图并使用读取器就好像您正在从字节读取一样0.

In the case of XMLHttpRequest (assuming the browser supports the newer interface) the data will be streamed on send, and constrained by the bounds of the blob. Basically, it will work the same way you'd imagine it to work if you sent a file pointer to a stream method (which is basically what's going on under the covers). https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data#Sending_binary_data

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

Essentially, it's a lazy reader. If the blob is already loaded/read from the file system, or was created in memory, it's just going to use that. When you're using a File though, it'll be lazily loaded and streamed asynchronously out of the main thread.

本质上,它是一个懒惰的读者。如果 blob 已经从文件系统加载/读取,或者是在内存中创建的,它就会使用它。但是,当您使用 File 时,它​​将被延迟加载并从主线程异步流式传输。

The basic logic here is that the browser devs never want a read to happen synchronously because it could block the main thread, so all of the API's are designed around that core philosophy. Notice how Blob.slice() is synchronous - that's how you know it's not actually doing any IO, it's just setting up bounds and (possibly) file pointers.

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