ファイルやフォルダが存在するか確認する

Recipe ID: fs-012

指定したファイルやディレクトリが実際に存在するかどうかを確認する方法を紹介します。
ファイルの読み込み前や、新規作成時の上書き防止チェックなど、ファイル操作の基本となる重要な機能です。

前提条件

このレシピを使用するには、@tauri-apps/plugin-fs プラグインが必要です。

1. プラグインのインストール

プロジェクトのルートディレクトリで以下のコマンドを実行してプラグインを追加します。

npm run tauri add fs

2. Permissions (権限) の設定

src-tauri/capabilities/default.json に以下の権限を追加します。

{
  "permissions": [
    ...,
    {
      "identifier": "fs:allow-exists",
      "allow": [{ "path": "$APPLOCALDATA/**" }]
    },
    {
      "identifier": "fs:allow-read-text-file",
      "allow": [{ "path": "$APPLOCALDATA/**" }]
    },
    {
      "identifier": "fs:allow-mkdir",
      "allow": [{ "path": "$APPLOCALDATA/**" }]
    }
  ]
}

※ 上記の例では $APPLOCALDATABaseDirectory.AppLocalData)配下での存在確認、読み込み、ディレクトリ作成を許可しています。アクセスするディレクトリに応じて、パス変数を指定してください。スコープが設定されていないディレクトリにはアクセスできません。

1. フロントエンドから作成する (TypeScript)

@tauri-apps/plugin-fsexists 関数を使用します。

ファイルの存在確認

ファイルが存在する場合のみ読み込む、といった処理に使用します。

import { exists, readTextFile, BaseDirectory } from '@tauri-apps/plugin-fs';

async function roadConfigSafely() {
  const fileName = 'config.json';
  
  try {
    // 存在確認
    const isExists = await exists(fileName, {
      baseDir: BaseDirectory.AppLocalData,
    });

    if (isExists) {
      const content = await readTextFile(fileName, {
        baseDir: BaseDirectory.AppLocalData,
      });
      console.log('設定を読み込みました:', content);
    } else {
      console.log('設定ファイルが見つかりません。デフォルト値を使用します。');
    }
  } catch (err) {
    console.error('エラー:', err);
  }
}

ディレクトリの存在確認

ディレクトリが存在しない場合に新規作成する、といった処理に使用します。

import { exists, mkdir, BaseDirectory } from '@tauri-apps/plugin-fs';

async function ensureLogDirectory() {
  const dirName = 'logs';

  try {
    const dirExists = await exists(dirName, {
      baseDir: BaseDirectory.AppLocalData,
    });

    if (!dirExists) {
      // 存在しなければ作成
      await mkdir(dirName, { baseDir: BaseDirectory.AppLocalData });
      console.log('logs ディレクトリを作成しました');
    }
  } catch (err) {
    console.error('ディレクトリ確認エラー:', err);
  }
}

2. バックエンドから作成する (Rust)

Rust の std::path::Path を使用して確認します。

ファイル・ディレクトリの存在確認

use std::path::Path;

#[tauri::command]
fn check_file_exists(path: String) -> bool {
    // ファイルでもディレクトリでも存在すれば true
    Path::new(&path).exists()
}

ファイルかどうか、ディレクトリかどうかの確認

use std::path::Path;

#[tauri::command]
fn check_path_type(path: String) -> String {
    let p = Path::new(&path);
    if p.is_file() {
        "File".to_string()
    } else if p.is_dir() {
        "Directory".to_string()
    } else if p.exists() {
        "Other (Symlink etc)".to_string()
    } else {
        "Not Found".to_string()
    }
}

補足

  • exists: Rust では path.exists() メソッドを使用します。
  • TOCTOU: exists チェック直後にファイルが削除されたり作成されたりする可能性(Time-of-Check to Time-of-Use 問題)があるため、クリティカルな処理では exists に頼らず、直接操作してエラーハンドリングを行う方が安全な場合があります。