🙆

アップロードされたファイルの保存方法(ディレクトリ)

2025/02/19に公開

Itemの登録機能を作るために、イメージをローカルティレクトに保存

ファイルの保存(saveFile)

fspath は、Node.js でファイルシステムを操作するための標準モジュールです。

  • fs: ファイルシステムを扱うモジュールで、ファイルを読み込んだり書き込んだりする操作を行います。ファイルを作成したり、内容を保存する際に使われます。
  • path: ファイルパスを操作するためのモジュールで、ファイルやディレクトリのパスを安全かつ効率的に結合したり処理したりとができます。

ファイルパスの保存方法

  1. パスの作成: path.join() を使って、現在の作業ディレクトリ(process.cwd())、public ディレクトリ、そしてアップロード先のディレクトリを結合して、ファイルパスを作成します。

    const uploadDir = path.join(process.cwd(), 'public', directory);
    

    このコードは、現在の作業ディレクトリの public フォルダ内にある directory というサブフォルダを含むパスを生成します。

  2. ファイルの拡張子を取得: アップロードされたファイルの拡張子(.png や .jpg など)を path.extname() メソッドで取得します。

    const extension = path.extname(file.name);
    
  3. ユニークなファイル名の生成: randomUUID() を使ってユニークなファイル名を生成し、それに拡張子を結合します。

    const uniqueFileName = `${randomUUID()}${extension}`;
    
  4. 最終的なファイルパスの結合: 再度 path.join() を使って、最終的に保存するファイルのパスを作成します。

    const filePath = path.join(uploadDir, uniqueFileName);
    
  5. ファイルの保存: 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());
  1. file.arrayBuffer(): このメソッドは、Fileオブジェクト(アップロードされたファイル)からファイルの内容をArrayBuffer(生のバイナリデータ)として取得します。file.arrayBuffer()は非同期的に動作するため、awaitを使ってその完了を待ちます。

  2. 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を使って、ファイルをサーバーの適切な場所に保存します。

写真を保存する流れ:

  1. フロントエンドからformDataを使って画像をサーバーに送信します。
  2. フロントからもらった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
    };
  1. サーバー側では、受け取った画像ファイルをBufferに変換し、指定したディレクトリに保存します。
const { fileName: mainImgName } = await saveFile(data.mainImg, 'uploads');

saveFile関数では、ファイルを受け取って、以下のように保存します:

  • ファイルの拡張子を取得して一意の名前を生成(UUIDを使用)
  • その名前でファイルを指定されたディレクトリに保存
const buffer = Buffer.from(await file.arrayBuffer());  // バイナリデータを取得
fs.writeFileSync(filePath, buffer);  // ファイルを保存

これにより、サーバー上に画像が保存され、クライアントにはそのファイルのパスが返されます。画像ファイルは静的なコンテンツとして利用されることが多いので、publicディレクトリなどの静的なフォルダに保存することが一般的です。

  • 写真保存の方法: ファイルを受け取った後、Bufferに変換して、指定したディレクトリに保存します。保存した画像のパスは、クライアント側に返され、アクセス可能になります。

ファイルアップロードフォーム(クライアント側)

  1. 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は、バイナリデータ(mainImgsubImg)を含むことができ、サーバーに送信する際に使われます。サーバー側では、formDataを使ってファイルとその他のデータを簡単に処理できます。

Discussion