0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

File API周りを整理してみた

Last updated at Posted at 2024-11-24

CSVデータをインポートする実装で、FileAPI周りでBlobとかArrayBufferとかよく見かける、名前だけ知ってるもの達を整理してみた。

CSVとは

そもそもCSVファイルとは、Comma Separated Valuesの略で、各項目がカンマ(,)で区切られたテキストデータのことです。データの容量が軽く、読み書きや編集が容易であるという特徴があります。

CSVファイルとExcelファイルの最も大きな違いは「互換性が高いか、装飾・機能の自由度が高いか」ということです。

拡張子「.csv」のCSVファイルは互換性が高く、Excelのみならずメモ帳、メールソフト、データベースソフトなどほとんどのソフトに取り込んで閲覧、編集することが可能です。そのため、Excelファイルを扱えるかが不明な相手とデータのやり取りを行う際はCSVに変換される場合が多いです。

データのじかん から引用

FIle API

FIle API は、ウェブアプリケーションがローカルマシンにあるファイルへアクセスしてJavaScriptで操作できるようにするためのAPIです。

その中の1つであるFileReaderを使って、アップロード、インポートなどが行われる

FileReader API

その名の通り、Fileオブジェクトを実際に読み込む

読み込みメソッド
readAsArrayBuffer : ファイルをArrayBufferとして読み込む
readAsText : ファイルをテキストとして読み込む
readAsDataURL : ファイルをDataURLとして読み込む
readAsBinaryString : ファイルをバイナリ形式で読み込む

サンプル

CSVをインポートする流れを以下のライブラリを用いて実装するサンプルです。

使用ライブラリ
ExcelJS : JSでExcelファイルを扱うようにできるライブラリ
Stream-Browserify : NodeのストリームAPIをブラウザで動かすライブラリ

ExcelJSのCSV読み込みの仕様
streamで渡さないといけない (以下ドキュメントより引用)

// read from a stream
const workbook = new Excel.Workbook();
const worksheet = await workbook.csv.read(stream);

以下CSVファイルをインポートして、streamに変換し、ExcelJSに渡すまでのサンプルです。

// JSでExcelファイルを扱うようにできるライブラリ
import ExcelJS from 'exceljs'
// NodeのストリームAPIをブラウザで動かすライブラリ
import { Readable } from 'stream-browserify'
import { Buffer } from 'buffer'


// グローバルスコープで利用できるのでインポートしなくても利用できる
const reader = new FileReader();
// リーダーにファイルをArrayBufferとして読み込む
reader.readAsArrayBuffer(file);
// 読み込みが成功して完了したら、以下のonloadメソッド内で読み込み結果が見れる
// この場合はArrayBufferデータ
reader.onload = () => {
  // リーダーがArrayBufferで読み込んだデータ
  const contents = reader.result
    
  // ExcelJSのインスタンスを作成
  const workbook = new ExcelJS.Workbook()
    
  // ArrayBufferをBufferObjectに変換
  const buffer = Buffer.from(contents)
    
  // ExcelJSがストリームからデータを読み取れるようにする
  const stream = new Readable()
  stream.push(buffer)
    
  // ストリームの終了
  stream.push(null)
    
  // ExcelJSのCSVリーダーにストリームを渡す
  await workbook.csv.read(stream)

  return workbook.worksheets
}

処理フローをまとめると
・ユーザーがFileを選択
・FileをArrayBufferとして読み込む
・読み込みが完了したら、resultプロパティにArrayBufferが格納される
・ArrayBufferをBufferに変換する
・BufferをReadable Streamに変換する
・Readable StreamをExcelJSのCSVリーダーメソッドに渡すと、JSで扱えるデータにしてくれる

JavaScriptで扱えるバイナリデータ

ArrayBuffer, Uint8Array, DataView, Blob, File, etc.
基本となるバイナリオブジェクトは ArrayBuffer です。これは固定長の連続したメモリ領域への参照です。

バイナリデータとは

0と1の2進数で表現されるデータのことを指します。コンピューターはこの形式のデータを扱うことが得意であり、多くのデータがバイナリーデータとして保存されます。例えば、画像、音声、動画、プログラムなどがバイナリーデータの形式で保存されています。

1. ArrayBuffer

JavaScript でバイナリデータを扱うときには ArrayBuffer を使うのが便利です。 ArrayBuffer は固定長のバイナリデータバッファを表します。
File API の FileReader などはデータを読み取った結果を ArrayBuffer として返します。そのため 「バイナリデータを使う時は ArrayBuffer を活用する」と覚えておくと、わかりやすいです。

ArrayBuffer は Array とは何の共通点もありませんので、配列データではない。
長さは固定で、増減することはできません。
メモリの中で、長さちょうどのスペースをとります。
個々のバイトにアクセスするには、buffer[index] ではなく、別の “view” オブジェクトが必要です。

2. Blob

BlobはBinary Large Objectの略
一般的なバイナリデータをJavaScriptで扱えるようにしたり、新しく生成することができます。

バイナリデータを簡単に説明すると「0」と「1」で表現される2進数だけでテキストや画像などをデータ化したものになります。また、Blobを拡張してブラウザ上からファイルを読み込んだりダウンロードするFile APIも一緒によく使われます。

JavaScriptのネイティブフォーマットではないデータを表すために使用されます。簡単に言うと、Blobは画像、zipファイル、オーディオファイルなど、さまざまなタイプのデータを扱うために使われます。

3. File

ファイルについての情報を提供したり、ウェブページ内の JavaScript からその内容にアクセスできるようにしたりします。Blobを継承してる

4. Buffer

Node.jsでは、文字列とバイナリデータ(バイト列)はまったく別のものとして扱われる。前者を扱うためのクラスがStringで、後者を扱うNode.js独自のクラスがBuffer。
Node.jsでは文字列とバイト列は厳密に区別されており、文字列の格納にはStringクラスを、バイト列の格納にはBufferクラスを利用するようになっている。

ストリームAPI

データを逐次的に読み込みながら処理したいときに利用するAPI
以下の3つの要素がある
ReadableStream データソースからデータを読み出してストリームとして提供する
TransformStream ストリームから受け取ったデータを変換してストリームとして提供する
WritableStream ストリームから受け取ったデータをデータソースに書き込む

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?