name: tauri description: Tauri路径处理、跨平台文件操作和API使用。当在Tauri前端代码中处理文件路径、访问文件系统API或处理桌面应用中的平台差异时使用。
Tauri路径处理
上下文检测
在选择路径API之前,确定您的执行上下文:
| 上下文 | 位置 | 正确的API |
|---|---|---|
| Tauri前端 | apps/*/src/**/*.ts, apps/*/src/**/*.svelte |
@tauri-apps/api/path |
| Node.js/Bun后端 | packages/**/*.ts, CLI工具 |
Node.js path模块 |
规则:如果代码在浏览器(Tauri webview)中运行,使用Tauri的路径API。如果在Node.js/Bun中运行,使用Node.js的path模块。
从@tauri-apps/api/path可用的函数
路径操作
| 函数 | 目的 | 示例 |
|---|---|---|
join(...paths) |
使用平台分隔符合并路径段 | await join(baseDir, 'workspaces', id) |
dirname(path) |
获取父目录 | await dirname('/foo/bar/file.txt') → /foo/bar |
basename(path, ext?) |
获取文件名,可选去除扩展名 | await basename('/foo/bar.txt', '.txt') → bar |
extname(path) |
获取文件扩展名 | await extname('file.txt') → .txt |
normalize(path) |
解析..和.段 |
await normalize('/foo/bar/../baz') → /foo/baz |
resolve(...paths) |
解析为绝对路径 | await resolve('relative', 'path') |
isAbsolute(path) |
检查路径是否为绝对 | await isAbsolute('/foo') → true |
平台常量
| 函数 | 目的 | 返回 |
|---|---|---|
sep() |
平台路径分隔符 | \\ on Windows, / on POSIX |
delimiter() |
平台路径分隔符 | ; on Windows, : on POSIX |
基础目录
| 函数 | 目的 |
|---|---|
appLocalDataDir() |
应用的本地数据目录 |
appDataDir() |
应用的漫游数据目录 |
appConfigDir() |
应用的配置目录 |
appCacheDir() |
应用的缓存目录 |
appLogDir() |
应用的日志目录 |
tempDir() |
系统临时目录 |
resourceDir() |
应用的资源目录 |
resolveResource(path) |
相对于资源解析路径 |
模式
构建路径(正确)
import { appLocalDataDir, dirname, join } from '@tauri-apps/api/path';
// 合并路径段 - 自动处理平台分隔符
const baseDir = await appLocalDataDir();
const filePath = await join(baseDir, 'workspaces', workspaceId, 'data.json');
// 获取父目录 - 比手动切片更清晰
const parentDir = await dirname(filePath);
await mkdir(parentDir, { recursive: true });
记录路径(例外)
对于人类可读的日志输出,硬编码的/是可接受的,因为它不用于文件系统操作:
// 对日志OK - 跨平台一致的日志输出
const logPath = pathSegments.join('/');
console.log(`[Persistence] Loading from ${logPath}`);
反模式
从不:手动字符串连接
// 错误:硬编码分隔符在Windows上会中断
const filePath = baseDir + '/' + 'workspaces' + '/' + id;
// 错误:模板字面量中的硬编码分隔符
const filePath = `${baseDir}/workspaces/${id}`;
// 好:使用join()
const filePath = await join(baseDir, 'workspaces', id);
从不:手动提取父目录
// 错误:手动切片容易出错
const parentSegments = pathSegments.slice(0, -1);
const parentDir = await join(baseDir, ...parentSegments);
// 好:使用dirname()
const parentDir = await dirname(filePath);
从不:在文件系统操作中使用硬编码分隔符
// 错误:Windows使用反斜杠
const configPath = appDir + '/config.json';
// 好:平台无关
const configPath = await join(appDir, 'config.json');
从不:假设路径格式
// 错误:在Windows路径上分割`/`会失败
const parts = filePath.split('/');
// 好:使用dirname/basename进行提取
const dir = await dirname(filePath);
const file = await basename(filePath);
导入模式
始终从@tauri-apps/api/path导入:
import {
appLocalDataDir,
dirname,
join,
basename,
extname,
normalize,
resolve,
sep,
} from '@tauri-apps/api/path';
关于异步的注意事项
所有Tauri路径函数都是异步的,因为它们通过IPC与Rust后端通信。始终await它们:
// 所有路径操作返回Promise
const baseDir = await appLocalDataDir();
const filePath = await join(baseDir, 'file.txt');
const parent = await dirname(filePath);
const separator = await sep();
文件系统操作
使用@tauri-apps/plugin-fs进行文件操作,结合Tauri路径API:
import { appLocalDataDir, dirname, join } from '@tauri-apps/api/path';
import { mkdir, readFile, writeFile } from '@tauri-apps/plugin-fs';
async function saveData(segments: string[], data: Uint8Array) {
const baseDir = await appLocalDataDir();
const filePath = await join(baseDir, ...segments);
// 确保父目录存在
const parentDir = await dirname(filePath);
await mkdir(parentDir, { recursive: true });
await writeFile(filePath, data);
}