Closed4

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ヶ月前にクローズされました