6 个版本

0.1.4 2023 年 9 月 28 日
0.1.3 2023 年 5 月 10 日
0.1.2 2023 年 1 月 18 日
0.0.0 2022 年 12 月 20 日

#244 in 文件系统

44 每月下载量
用于 4 crates

Apache-2.0

93KB
1K SLoC

github crates.io docs.rs

Rust 的异步虚拟文件系统接口。

Lunchbox 提供了一个通用接口,可以用来与任何文件系统(例如本地文件系统、内存文件系统、zip 文件系统等)交互。此接口与 tokio::fs:: 紧密匹配,因此易于入门。

高级功能

  • 支持只读文件系统和读写文件系统
  • 内置本地文件系统实现
  • 异步接口
  • WASM 支持

入门指南

将 lunchbox 添加到您的 Cargo.toml 中

[dependencies]
lunchbox = "0.1"

步骤 1:加载文件系统

Lunchbox 在核心上提供 ReadableFileSystemWritableFileSystem trait。这些 trait 为 tokio::fs 中可用的所有函数提供类似功能。

我们将使用内置的 LocalFS,但您可以使用实现上述文件系统 trait 中的任何内容。

use lunchbox::ReadableFileSystem;
use lunchbox::LocalFS;

// Create a lunchbox filesystem that uses the root of your local filesystem as its root
let local_fs = LocalFS::new()?;

// Create a lunchbox filesystem that uses `/tmp` as its root.
// `/some/path` inside the filesystem would be translated to `/tmp/some/path`
// on your local filesystem
let local_fs = LocalFS::with_base_dir("/tmp").await?;

注意:使用 LocalFS 需要启用 localfs 功能

步骤 2:用它代替 tokio::fs::...

而不是

tokio::fs::canonicalize("/some/path").await

您将编写

local_fs.canonicalize("/some/path").await

详细信息

Path

我们不能直接使用 std::path::Path,因为它包含直接访问文件系统的函数(例如,exists)并且不是跨操作系统的可移植的(例如,Windows 上的路径与 Unix 上的路径不同)。

作为替代方案,我们使用 relative_path crate 来提供跨平台的路径。我们还提供了一个扩展 trait(LunchboxPathUtils)来添加像 exists 这样的方法。这作为 lunchbox::path::Pathlunchbox::path::PathBuf 提供。

午餐盒特质中的方法通常接受任何实现了 AsRef<lunchbox::path::Path> 的类型。这意味着你可以直接使用 strString,就像使用标准库中的路径一样。有关详细信息,请参阅 relative_path 文档。

特质方法

在以下方法中,请注意 PathType 仅是 AsRef<lunchbox::path::Path> + Send 的别名。

ReadableFileSystem 包含以下方法

// Open a file
async fn open(&self, path: impl PathType) -> Result<Self::FileType>
where
    Self::FileType: ReadableFile;

// These are almost identical to tokio::fs::...
async fn canonicalize(&self, path: impl PathType) -> Result<PathBuf>;
async fn metadata(&self, path: impl PathType) -> Result<Metadata>;
async fn read(&self, path: impl PathType) -> Result<Vec<u8>>;
async fn read_dir(&self, path: impl PathType) -> Result</* snip */>;
async fn read_link(&self, path: impl PathType) -> Result<PathBuf>;
async fn read_to_string(&self, path: impl PathType) -> Result<String>;
async fn symlink_metadata(&self, path: impl PathType) -> Result<Metadata>;

WritableFileSystem 包含

// Create a file
async fn create(&self, path: impl PathType) -> Result<Self::FileType>
where
    Self::FileType: WritableFile;

// Open a file with options
async fn open_with_opts(
    &self,
    opts: &OpenOptions,
    path: impl PathType,
) -> Result<Self::FileType>
where
    Self::FileType: WritableFile;

// These are almost identical to tokio::fs::...
async fn copy(&self, from: impl PathType, to: impl PathType) -> Result<u64>;
async fn create_dir(&self, path: impl PathType) -> Result<()>;
async fn create_dir_all(&self, path: impl PathType) -> Result<()>;
async fn hard_link(&self, src: impl PathType, dst: impl PathType) -> Result<()>;
async fn remove_dir(&self, path: impl PathType) -> Result<()>;
async fn remove_dir_all(&self, path: impl PathType) -> Result<()>;
async fn remove_file(&self, path: impl PathType) -> Result<()>;
async fn rename(&self, from: impl PathType, to: impl PathType) -> Result<()>;
async fn set_permissions(&self, path: impl PathType, perm: Permissions) -> Result<()>;
async fn symlink(&self, src: impl PathType, dst: impl PathType) -> Result<()>;
async fn write(&self, path: impl PathType, contents: impl AsRef<[u8]> + Send) -> Result<()>;

这些方法分别与 ReadableFileWritableFile 一起使用

/// A readable file
#[async_trait]
pub trait ReadableFile: AsyncRead
where
    Self: Sized,
{
    // These are almost identical to tokio::fs::File::...
    async fn metadata(&self) -> Result<Metadata>;
    async fn try_clone(&self) -> Result<Self>;
}

/// A file that supports both reads and writes
#[async_trait]
pub trait WritableFile: ReadableFile + AsyncWrite {
    // These are almost identical to tokio::fs::File::...
    async fn sync_all(&self) -> Result<()>;
    async fn sync_data(&self) -> Result<()>;
    async fn set_len(&self, size: u64) -> Result<()>;
    async fn set_permissions(&self, perm: Permissions) -> Result<()>;
}

请注意,所有 WritableFile 必须是 ReadableFile,所有 WritableFileSystem 必须是 ReadableFileSystem

WASM

对于 WASM 构建,接口的所有部分都去除了 SendSync 约束。

依赖

~2.4–4MB
~68K SLoC