アップロードされたファイルの保存方法(ディレクトリ)
Itemの登録機能を作るために、イメージをローカルティレクトに保存
ファイルの保存(saveFile)
fs
と path
は、Node.js でファイルシステムを操作するための標準モジュールです。
-
fs
: ファイルシステムを扱うモジュールで、ファイルを読み込んだり書き込んだりする操作を行います。ファイルを作成したり、内容を保存する際に使われます。 -
path
: ファイルパスを操作するためのモジュールで、ファイルやディレクトリのパスを安全かつ効率的に結合したり処理したりとができます。
ファイルパスの保存方法
-
パスの作成:
path.join()
を使って、現在の作業ディレクトリ(process.cwd()
)、public
ディレクトリ、そしてアップロード先のディレクトリを結合して、ファイルパスを作成します。const uploadDir = path.join(process.cwd(), 'public', directory);
このコードは、現在の作業ディレクトリの
public
フォルダ内にあるdirectory
というサブフォルダを含むパスを生成します。 -
ファイルの拡張子を取得: アップロードされたファイルの拡張子(.png や .jpg など)を
path.extname()
メソッドで取得します。const extension = path.extname(file.name);
-
ユニークなファイル名の生成:
randomUUID()
を使ってユニークなファイル名を生成し、それに拡張子を結合します。const uniqueFileName = `${randomUUID()}${extension}`;
-
最終的なファイルパスの結合: 再度
path.join()
を使って、最終的に保存するファイルのパスを作成します。const filePath = path.join(uploadDir, uniqueFileName);
-
ファイルの保存:
fs.writeFileSync()
を使用して、作成したパスにファイルを同期的に保存します。fs.writeFileSync(filePath, buffer);
このようにして、ファイルパスを設定し、アップロードされたファイルを指定した場所に保存することができます。
import { randomUUID } from "crypto";
import fs from 'fs';
import path from "path";
export const saveFile = async (file: File, directory: string) => {
//経路
const uploadDir = path.join(process.cwd(), 'public', directory);
const extension = path.extname(file.name);//.png など
const uniqueFileName = `${randomUUID()}${extension}`; //名前重複防止のため固有の名前を与える
const filePath = path.join(uploadDir, uniqueFileName); //経路を設定
// ファイル保存
const buffer = Buffer.from(await file.arrayBuffer());
fs.writeFileSync(filePath, buffer);
return { filePath: `/${directory}/${uniqueFileName}`, fileName: uniqueFileName }; // 파일 경로 반환
};
buffer
buffer
は、バイナリデータ(画像、音声、動画など)を効率的に扱うために使われます。
例えば、画像や音声ファイルなどのバイナリデータをメモリに格納して処理する。
const buffer = Buffer.from(await file.arrayBuffer());
-
file.arrayBuffer()
: このメソッドは、File
オブジェクト(アップロードされたファイル)からファイルの内容をArrayBuffer(生のバイナリデータ)として取得します。file.arrayBuffer()
は非同期的に動作するため、await
を使ってその完了を待ちます。 -
Buffer.from()
: このメソッドは、ArrayBuffer
からNode.jsのBuffer
オブジェクトを作成します。Buffer
はバイナリデータを効率的に格納できる構造であり、特にファイルの読み書きや通信データの処理に適しています。
その後、生成したbuffer
を使ってファイルを書き込みます:
fs.writeFileSync(filePath, buffer);
このコードは、指定したパス(filePath
)、先ほど作成したbuffer
を使ってファイルを保存します。
ファイルのアップロード(API "POST")
formDataを使ってFile情報取得 : formData
は、主にHTMLフォームから送信されるデータを扱うためのオブジェクトです。特にファイルを含むデータを送信する際には便利です。通常のJSON
では、バイナリデータ(例えば、画像ファイルやPDFファイルなど)を送信することはできませんが、formData
を使うことで、ファイルを含むフォームデータを簡単に送信できます。
写真を保存する方法
写真や画像ファイルを保存する場合、まず、サーバーにファイルをアップロードする必要があります。これには、fs
(ファイルシステムモジュール)とpath
を使って、ファイルをサーバーの適切な場所に保存します。
写真を保存する流れ:
- フロントエンドから
formData
を使って画像をサーバーに送信します。 - フロントからもらった
formData
をパーシング
const fromData = await request.formData();
// データー検証
const data: CreateItemRequest = {
name: fromData.get('name') as string,
price: Number(fromData.get('price')),
intro: fromData.get('intro') as string,
categoryId: Number(fromData.get('categoryId')),
mainImg: fromData.get('mainImg') as File, //FileData
subImg: fromData.get('subImg') as File, //FileData
};
- サーバー側では、受け取った画像ファイルを
Buffer
に変換し、指定したディレクトリに保存します。
const { fileName: mainImgName } = await saveFile(data.mainImg, 'uploads');
saveFile
関数では、ファイルを受け取って、以下のように保存します:
- ファイルの拡張子を取得して一意の名前を生成(UUIDを使用)
- その名前でファイルを指定されたディレクトリに保存
const buffer = Buffer.from(await file.arrayBuffer()); // バイナリデータを取得
fs.writeFileSync(filePath, buffer); // ファイルを保存
これにより、サーバー上に画像が保存され、クライアントにはそのファイルのパスが返されます。画像ファイルは静的なコンテンツとして利用されることが多いので、public
ディレクトリなどの静的なフォルダに保存することが一般的です。
-
写真保存の方法: ファイルを受け取った後、
Buffer
に変換して、指定したディレクトリに保存します。保存した画像のパスは、クライアント側に返され、アクセス可能になります。
ファイルアップロードフォーム(クライアント側)
- formタグでデーターを送る
フロントエンドでフォームデータ(例えば、商品名や価格、画像ファイルなど)を送信する場合、次のようにFormData
オブジェクトを使用して、複数のデータを一度に送信します:
const formDataToSend = new FormData();
formDataToSend.append('name', itemFormData.name);
formDataToSend.append('price', itemFormData.price.toString());
formDataToSend.append('intro', itemFormData.intro || '');
formDataToSend.append('categoryId', itemFormData.categoryId.toString());
formDataToSend.append('mainImg', itemFormData.mainImg || '');
formDataToSend.append('subImg', itemFormData.subImg || '');
このformData
は、バイナリデータ(mainImg
やsubImg
)を含むことができ、サーバーに送信する際に使われます。サーバー側では、formData
を使ってファイルとその他のデータを簡単に処理できます。
Discussion