Blob、File、ArrayBuffer、FileReader、FormData

197 阅读3分钟

Blod、ArrayBuffer与File

  • Bold为一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,包含大小、类型、名称、修改时间等属性,可以进行截取等方法。
    有的时候我们需要将Blob数据直接显示在网站上,通过URL.createObjectURL()返回的新url对象表示指定的 File对象或 Blob对象。注意:每个对象必须通过调用 URL.revokeObjectURL() 方法来释放。

     interface Blob {
         readonly size: number;
         readonly type: string;
         arrayBuffer(): Promise<ArrayBuffer>;
         slice(start?: number, end?: number, contentType?: string): Blob;
         stream(): ReadableStream;
         text(): Promise<string>;
     }
    
  • ArrayBuffer就是一个二进制数据通用的固定长度容器。通俗点说,就是内存上一段连续的二进制数据。我们可以对ArrayBuffer进行读写,但需要借助它提供的工具TypeArray或DataView

      interface ArrayBufferConstructor {
          readonly prototype: ArrayBuffer;
          new(byteLength: number): ArrayBuffer;
          isView(arg: any): arg is ArrayBufferView;
      }
      declare var ArrayBuffer: ArrayBufferConstructor;
    
  • File为Blob的一个子类,集成了Blob的所有属性和方法,也包含自己的一些方法。接口提供有关文件的信息,并允许网页中的 JavaScript 访问其内容。如果要读取File类中的数据就需要用到FileReader将其读取为不同格式的数据。通常,表示我们使用<input type="file">选择的FileList对象,或者是使用拖拽操作搞出的DataTransfer对象。

      interface File extends Blob {
          readonly lastModified: number;
          readonly name: string;
      }
    

    有时候我们需要将File对象显示在网页中,例如图片,可以通过FileReader将File转换为URL,

         var img = document.createElement("img");
            img.classList.add("obj");
            img.file = file;
            preview.appendChild(img); // 假设"preview"就是用来显示内容的 div
            var reader = new FileReader();
            reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
            reader.readAsDataURL(file);
    
  • Blob与ArrayBuffer的关系

    • 相同点: Blob和ArrayBuffer都是二进制的容器;
    • ArrayBuffer:ArrayBuffer更底层,就是一段纯粹的内存上的二进制数据,我们可以对其任何一个字节进行单独的修改,也可以根据我们的需要以我们指定的形式读取指定范围的数据
    • Blob:Blob就是将一段二进制数据做了一个封装,我们拿到的就是一个整体,可以看到它的整体属性大小、类型;可以对其分割,但不能了解到它的细节
    • 联系:Blob可以接受一个ArrayBuffer作为参数生成一个Blob对象,此行为就相当于对ArrayBuffer数据做一个封装,之后就是以整体的形式展现了
    • 应用上的区别:由于ArrayBuffer和Blob的特性,Blob作为一个整体文件,适合用于传输;而只有需要关注细节(比如要修改某一段数据时),才需要用到ArrayBuffer

FileReader、FormData

  • FormData它是XMLHttpRequest Level 2添加的一个新的接口,我们可以通过JavaScript用一些键值对来模拟一系列表单控件。FormData的最大优点就是,比起普通的ajax, 使用FormData我们可以异步上传一个二进制文件,而这个二进制文件,就是我们上面讲的Blob对象。
  • FileReader 前面提到Blob对象时一个只读对象,但它是一个二进制对象,如果直接读取就只能拿到一堆01数据,因此需要借助FileReader来读取。 通过FileReader可以将Blob读取为不同的格式。
interface FileReader extends EventTarget {
    readonly error: DOMException | null;
    onabort: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;
    onerror: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;
    onload: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;
    onloadend: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;
    onloadstart: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;
    onprogress: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;
    readonly readyState: number;
    readonly result: string | ArrayBuffer | null;
    abort(): void;
    readAsArrayBuffer(blob: Blob): void;
    readAsBinaryString(blob: Blob): void;
    readAsDataURL(blob: Blob): void; // 方法会读取指定的Blod与File对象,读取成功后的内容是base64编码
    readAsText(blob: Blob, encoding?: string): void;
    readonly DONE: number;
    readonly EMPTY: number;
    readonly LOADING: number;
    addEventListener<K extends keyof FileReaderEventMap>(type: K, listener: (this: FileReader, ev: FileReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
    removeEventListener<K extends keyof FileReaderEventMap>(type: K, listener: (this: FileReader, ev: FileReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}