🧊

Cloud StorageにアップしたtarファイルをCloud Functionで解凍する

2024/08/29に公開

はじめに

  • Cloud StorageにアップしたtarファイルをCloud Functionで解凍する方法をまとめました。
  • 覚書程度に残してありますので、汚いのはご了承ください😓(要望があれば綺麗にしようかと)

環境

  • Cloud Functions(第二世代)
  • Cloud Storage
  • Node.js

解凍するコード

# package.json
{
    "@google-cloud/functions-framework": "^3.0.0",
    "firebase-admin": "^12.0.0",
    "tar": "^7.0.0"
  }
}
// index.js
const functions = require("@google-cloud/functions-framework");
const admin = require("firebase-admin");
const tar = require("tar");
const path = require("path");
const os = require("os");
const fs = require("fs");

admin.initializeApp();

functions.http("decompressCsv", async (req, res) => {
  try {
    /**
     * バケット名を指定して、参照を取得し、tar.gz ファイルをダウンロードする
     * fileNameには、バケット以下のパスを指定する(例: hoge/fuga.tar.gz)
     */
    const bucket = admin.storage().bucket(req.query.bucketName);
    const file = bucket.file(req.query.fileName);

    // 一時ファイルパスを取得して、ファイルをダウンロード
    const tempFilePath = path.join(os.tmpdir(), path.basename(file.name));
    await file.download({ destination: tempFilePath });

    /**
     * tar.gz ファイルを解凍
     * 念の為、解凍先のディレクトリを別で作成しておく
     */
    const extractPath = path.join(os.tmpdir(), "extracted");
    await fs.promises.mkdir(extractPath, { recursive: true }); // ディレクトリがなければ作成
    await tar.x({ file: tempFilePath, cwd: extractPath });

    /**
     * 解凍された .csv ファイルを検索し、取得
     */
    const files = await fs.promises.readdir(extractPath);
    const csvFiles = files.filter((file) => file.endsWith(".csv"));
    if (csvFiles.length === 0) {
      throw new Error("No .csv files found in the extracted directory");
    }
    const csvFileName = csvFiles[0];
    const csvFilePath = path.join(extractPath, csvFileName);

    /**
     * 解凍したファイルを Cloud Storage にアップロード
     */
    const extractedFiles = await bucket.upload(csvFilePath, {
      // ここは、バケット以下のパスを指定する(例: hoge/fuga.csv)
      destination: "extracted/" + csvFileName,
    });

    console.log(
      `Extracted files: ${extractedFiles.map((file) => file.name).join(", ")}`
    );

    /**
     * 元の tar.gz ファイルを削除
     */
    await bucket.file(file.name).delete();

    res.send(`DONE!`);
  } catch (e) {
    console.error("Error", e);

    res.status(500).send(`Error: ${e.message}`);
  }
});
GitHubで編集を提案

Discussion