指定したディレクトリ(フォルダ)に含まれるファイルやサブディレクトリの一覧を取得する方法を紹介します。
ファイルエクスプローラーのような機能や、特定のフォルダ内の画像一覧を表示するギャラリー機能などを実装する際に必須となります。
前提条件
このレシピを使用するには、@tauri-apps/plugin-fs プラグインが必要です。
1. プラグインのインストール
プロジェクトのルートディレクトリで以下のコマンドを実行してプラグインを追加します。
npm run tauri add fs
2. Permissions (権限) の設定
src-tauri/capabilities/default.json に以下の権限を追加します。
{
"permissions": [
...,
{
"identifier": "fs:allow-read-dir",
"allow": [{ "path": "$DOCUMENT/**" }, { "path": "$RESOURCE/**" }]
}
]
}
※ 上記の例では $DOCUMENT(BaseDirectory.Document)および $RESOURCE(BaseDirectory.Resource)配下のディレクトリ一覧取得を許可しています。アクセスするディレクトリに応じて、パス変数を指定してください。スコープが設定されていないディレクトリにはアクセスできません。
1. フロントエンドから作成する (TypeScript)
@tauri-apps/plugin-fs の readDir 関数を使用します。
基本的な一覧取得
ディレクトリ内のエントリを取得し、名前と種類(ファイルかディレクトリか)をコンソールに表示します。
import { readDir, BaseDirectory } from '@tauri-apps/plugin-fs';
async function listFiles() {
try {
// $DOCUMENT/projects フォルダの中身を取得
const entries = await readDir('projects', {
baseDir: BaseDirectory.Document,
});
for (const entry of entries) {
console.log(`Name: ${entry.name}`);
console.log(`Type: ${entry.isDirectory ? 'Directory' : 'File'}`);
}
} catch (err) {
console.error('ディレクトリ読み込みエラー:', err);
}
}
特定の拡張子(例: .png)のみフィルタリングする
import { readDir, BaseDirectory } from '@tauri-apps/plugin-fs';
// BaseDirectory.Resource を使用する場合、
// src-tauri/tauri.conf.json の bundle > resources に対象フォルダ(例: "images/*")を追加する必要があります。
async function listImages() {
const entries = await readDir('images', {
baseDir: BaseDirectory.Resource, // リソースフォルダ内の images を想定
});
// .png で終わるファイルのみ抽出
const pngFiles = entries.filter(
(entry) => entry.isFile && entry.name.endsWith('.png')
);
console.log('PNG Images:', pngFiles.map(e => e.name));
}
※ 上記の例で BaseDirectory.Resource を使用するには、src-tauri/tauri.conf.json にリソース設定が必要です。
// src-tauri/tauri.conf.json
{
"bundle": {
"resources": [
// src-tauri/images フォルダをリソースとして含める例
"images/*"
]
}
}
2. バックエンドから作成する (Rust)
Rust の std::fs::read_dir を使用します。
ディレクトリ一覧の取得
use std::fs;
use serde::Serialize;
#[derive(Serialize)]
struct FileEntry {
name: String,
is_dir: bool,
}
#[tauri::command]
fn list_directory(path: String) -> Result<Vec<FileEntry>, String> {
let mut entries = Vec::new();
// read_dir はイテレータを返します
let dir = fs::read_dir(path).map_err(|e| e.to_string())?;
for entry in dir {
let entry = entry.map_err(|e| e.to_string())?;
let path = entry.path();
let name = path.file_name()
.and_then(|n| n.to_str())
.unwrap_or_default()
.to_string();
let is_dir = path.is_dir();
entries.push(FileEntry { name, is_dir });
}
Ok(entries)
}
補足
- 隠しファイル: OS によっては隠しファイル(ドットファイルなど)が含まれる場合があります。必要に応じてフィルタリングしてください。
- 再帰探索: JS 側も Rust 側(標準ライブラリのみの場合)も、デフォルトでは再帰探索しません。Rust には
walkdirクレートなどの便利なライブラリがあります。