Closed4
Tauriでファイルをローカルファイル一覧を読み込む

Tauriでファイル一覧を読み込んでフロントに渡せるようにする

Rust側にファイル一覧を読み込む関数を定義する。
invoke_handlerにlist_directoryを登録。
src-tauri/src/lib.rs
#[tauri::command]
fn list_directory(path: String) -> Result<Vec<FileEntry>, String> {
let path = Path::new(&path);
if !path.is_dir() {
return Err("指定されたパスはディレクトリではありません".to_string());
}
let mut entries = Vec::new();
match fs::read_dir(path) {
Ok(read_dir) => {
for entry in read_dir {
if let Ok(entry) = entry {
let file_type = entry.file_type().unwrap();
entries.push(FileEntry {
name: entry.file_name().into_string().unwrap_or_default(),
is_dir: file_type.is_dir(),
})
}
}
Ok(entries)
}
Err(err) => Err(format!("ディレクトリの読み込みに失敗しました: {}", err)),
}
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet, list_directory])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
lib.rsの呼び出しは、tauri_test_libとしている(デフォルト)。
src-tauri/Cargo.toml
[lib]
# The `_lib` suffix may seem redundant but it is necessary
# to make the lib name unique and wouldn't conflict with the bin name.
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
name = "tauri_test_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
src-tauri/src/main.rs
fn main() {
tauri_test_lib::run()
}

※フロント側は、Nextjs側で実装している。
Rustのinvokeで、list_directoryを呼び出す。
front/app/page.tsx
"use client";
import { useState } from "react";
import { invoke } from "@tauri-apps/api/core";
type FileEntry = {
name: string;
is_dir: boolean;
};
const Home = () => {
const [directoryPath, setDirectoryPath] = useState("/path/to/directory");
const [files, setFiles] = useState<FileEntry[]>([]);
const [error, setError] = useState("");
const fetchFiles = async () => {
try {
setError("");
const result = await invoke<FileEntry[]>("list_directory", {
path: directoryPath,
});
setFiles(result);
} catch (err) {
setError("ディレクトリの読み込みに失敗しました");
console.error("Error", err);
}
};
return (
<div>
<input
type="text"
value={directoryPath}
onChange={(e) => setDirectoryPath(e.target.value)}
/>
<button onClick={fetchFiles}>取得</button>
{error && <p>{error}</p>}
<ul>
{files.map((file, index) => (
<li key={index}>
{file.is_dir ? "📁" : "📄"} {file.name}
</li>
))}
</ul>
</div>
);
};
export default Home;

出力された結果が以下。
フォルダとファイルがそれぞれ出力されている。
このスクラップは2ヶ月前にクローズされました