テキストファイルを読み込む

Recipe ID: fs-001

ローカルファイルシステム上にあるテキストファイル(.txt, .json, .md など)の内容を文字列として読み込む方法を紹介します。
Tauri ではセキュリティ上の理由から、ファイルアクセスには厳格な制限(スコープ)が設けられています。

前提条件

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

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

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

npm run tauri add fs

2. Permissions (権限) の設定

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

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

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

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

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

基本ディレクトリ(BaseDirectory)を指定して読み込む

Tauri が提供する BaseDirectory 列挙型を使うことで、OS ごとの標準的なパス(ドキュメント、アプリデータなど)を簡単に指定できます。

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

async function loadData() {
  try {
    // $APPLOCALDATA/config.json を読み込む
    const contents = await readTextFile('config.json', {
      baseDir: BaseDirectory.AppLocalData
    });
    
    console.log('ファイルの内容:', contents);
    return contents;
  } catch (err) {
    console.error('読み込みエラー:', err);
  }
}

参考: BaseDirectory

絶対パスで読み込む

絶対パスを使用する場合も、そのパスが capabilities のスコープで許可されている必要があります。

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

// 事前に Permissions で "/tmp/**" や "C:\\Temp\\**" などが許可されている必要があります
const absolutePath = '/path/to/my/file.txt';

const text = await readTextFile(absolutePath);

JSON ファイルを読み込んでオブジェクトにする

設定ファイルなどを読み込む際の一般的なパターンの例です。

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

interface AppConfig {
  theme: string;
  version: number;
}

async function loadConfig(): Promise<AppConfig | null> {
  try {
    const jsonString = await readTextFile('settings.json', {
      baseDir: BaseDirectory.AppConfig
    });
    return JSON.parse(jsonString) as AppConfig;
  } catch (e) {
    console.warn('設定ファイルが見つかりません:', e);
    return null;
  }
}

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

Rust の標準ライブラリ std::fs を使用してファイルを読み込みます。

基本的な読み込み

use std::fs;

#[tauri::command]
fn read_text_file(path: String) -> Result<String, String> {
    // ファイル存在確認などを含めることも可能
    fs::read_to_string(path).map_err(|e| e.to_string())
}

特定のディレクトリパスを取得して読み込む

Tauri のパスリゾルバーを使用して、AppLocalData などの標準ディレクトリを取得します。

use tauri::Manager; // app_handle.path() を使うために必要
use std::fs;

#[tauri::command]
fn read_config_file(app: tauri::AppHandle) -> Result<String, String> {
    // AppLocalData ディレクトリのパスを取得
    let local_data_dir = app.path().app_local_data_dir()
        .map_err(|e| e.to_string())?;

    // パスを結合
    let file_path = local_data_dir.join("config.json");

    // 読み込み
    fs::read_to_string(file_path).map_err(|e| e.to_string())
}

補足

  • 非同期処理: フロントエンド(readTextFile)は Promise を返しますが、Rust の std::fs は同期処理です。大きなファイルを読み込む場合や、UI スレッドをブロックしたくない場合は、Rust 側でも tokio::fs を使用して async 関数にするか、std::thread を使うなどの工夫が必要な場合があります(ただし Tauri コマンドはデフォルトでスレッドプール上で実行されるため、通常のファイル操作であればそのまま std::fs を使っても UI はフリーズしません)。
  • スコープ(Scope):
    • フロントエンド: capabilities で許可された範囲内でのみアクセス可能です。
    • バックエンド (Rust): OS のユーザー権限の範囲内であればどこでもアクセス可能ですが、tauri-plugin-fs の API を Rust から使う場合はスコープ制限が適用されます。std::fs を直接使う場合はスコープ制限を受けません。
  • BaseDirectory: クロスプラットフォーム対応のために重要です。
    • AppLocalData: Windowsでは AppData/Local/{AppIdentifier}、macOSでは ~/Library/Application Support/{AppIdentifier} などにマッピングされます。