跳到主要内容
版本:v0.9.1

Filesystem API

文件系统辅助能力位于 ptool.fsp.fs 下。

ptool.fs.read

v0.1.0 - 引入。

ptool.fs.read(path) 按原始字节读取文件,并返回一个 Lua 字符串。

  • path(string,必填):文件路径。
  • 返回:string

说明:

  • 返回的 Lua 字符串会精确包含磁盘上的文件字节。
  • 文本文件依然可以像以前一样读取,同时也支持二进制文件。

示例:

local content = ptool.fs.read("README.md")
print(content)

local png = ptool.fs.read("logo.png")
print(#png)

ptool.fs.write

v0.1.0 - 引入。

ptool.fs.write(path, content) 将 Lua 字符串按原始字节写入文件,并覆盖已有内容。

  • path(string,必填):文件路径。
  • content(string,必填):要写入的内容。

说明:

  • content 会逐字节写入。
  • 内嵌 NUL 字节和非 UTF-8 字节都会被保留。

示例:

ptool.fs.write("tmp/hello.txt", "hello\n")
ptool.fs.write("tmp/blob.bin", "\x00\xffABC")

ptool.fs.append

v0.8.0 - 引入。

ptool.fs.append(path, content) 将 Lua 字符串按原始字节追加到文件末尾。如果文件不存在,则会创建该文件。

  • path(string,必填):文件路径。
  • content(string,必填):要追加的内容。

说明:

  • content 会逐字节写入到文件末尾。
  • 内嵌 NUL 字节和非 UTF-8 字节都会被保留。

示例:

ptool.fs.append("tmp/log.txt", "first line\n")
ptool.fs.append("tmp/log.txt", "second line\n")

ptool.fs.open

v0.8.0 - 引入。

ptool.fs.open(path[, mode]) 打开一个本地文件,并返回一个 File 对象。

参数:

  • path(string,必填):文件路径。
  • mode(string,选填):文件模式。默认为 "r"

支持的模式:

  • "r":以读取方式打开。
  • "w":以写入方式打开,截断已有内容,并在需要时创建文件。
  • "a":以追加方式打开,并在需要时创建文件。
  • "r+":以读写方式打开,不截断内容。
  • "w+":以读写方式打开,截断已有内容,并在需要时创建文件。
  • "a+":以读取和追加方式打开,并在需要时创建文件。

说明:

  • 模式中可以包含 b,例如 "rb""w+b"
  • aa+ 的写入始终会落到文件末尾。

示例:

local file = ptool.fs.open("tmp/log.txt", "a+")
file:write("hello\n")
file:flush()
file:close()

File

v0.8.0 - 引入。

File 表示由 ptool.fs.open() 返回的一个已打开的本地文件句柄。

它被实现为一个 Lua userdata。

方法:

  • file:read([n]) -> string
  • file:write(content) -> nil
  • file:flush() -> nil
  • file:seek([whence[, offset]]) -> integer
  • file:close() -> nil

read

v0.8.0 - 引入。

规范 API 名称:ptool.fs.File:read

file:read([n]) 从当前文件位置读取字节,并将其作为 Lua 字符串返回。

  • n(integer,选填):最多读取的字节数。省略时会从当前位置一直读取到 EOF。
  • 返回:string

行为说明:

  • 在 EOF 处会返回空字符串。
  • 读取的是原始字节,因此二进制数据会被原样保留。

示例:

local file = ptool.fs.open("README.md")
local prefix = file:read(16)
local rest = file:read()
file:close()

write

v0.8.0 - 引入。

规范 API 名称:ptool.fs.File:write

file:write(content) 会在当前文件位置写入一个 Lua 字符串。

  • content(string,必填):要写入的字节。

行为说明:

  • 会按提供的内容精确写入原始字节。
  • 对于 append 模式的句柄,写入总是追加到文件末尾。

flush

v0.8.0 - 引入。

规范 API 名称:ptool.fs.File:flush

file:flush() 会将缓冲的文件写入刷新到操作系统。

seek

v0.8.0 - 引入。

规范 API 名称:ptool.fs.File:seek

file:seek([whence[, offset]]) 会移动当前文件位置。

  • whence(string,选填):"set""cur""end" 之一。默认为 "cur"
  • offset(integer,选填):相对于 whence 的字节偏移量。默认为 0
  • 返回:integer

行为说明:

  • 返回新的绝对文件位置。
  • "set" 要求 offset 必须为非负数。

示例:

local file = ptool.fs.open("tmp/data.bin", "w+")
file:write("abcdef")
file:seek("set", 2)
print(file:read(2)) -- cd
file:close()

close

v0.8.0 - 引入。

规范 API 名称:ptool.fs.File:close

file:close() 会关闭该文件句柄。

行为说明:

  • 关闭后,这个文件句柄将不能再继续使用。

ptool.fs.mkdir

v0.1.0 - 引入。

ptool.fs.mkdir(path) 创建目录。如果父目录不存在,会递归创建。

  • path(string,必填):目录路径。

示例:

ptool.fs.mkdir("tmp/a/b")

ptool.fs.exists

v0.1.0 - 引入。

ptool.fs.exists(path) 检查路径是否存在。

  • path(string,必填):文件或目录路径。
  • 返回:boolean

示例:

if ptool.fs.exists("tmp/hello.txt") then
print("exists")
end

ptool.fs.is_file

v0.6.0 - 引入。

ptool.fs.is_file(path) 检查路径是否存在且是否为普通文件。

  • path(string,必填):要检查的路径。
  • 返回:boolean

示例:

if ptool.fs.is_file("tmp/hello.txt") then
print("file")
end

ptool.fs.is_dir

v0.6.0 - 引入。

ptool.fs.is_dir(path) 检查路径是否存在且是否为目录。

  • path(string,必填):要检查的路径。
  • 返回:boolean

示例:

if ptool.fs.is_dir("tmp") then
print("dir")
end

ptool.fs.remove

v0.6.0 - 引入。

ptool.fs.remove(path[, options]) 删除文件、符号链接或目录。

  • path(string,必填):要删除的路径。
  • options(table,可选):删除选项。支持:
    • recursive(boolean,可选):是否递归删除目录。默认值为 false
    • missing_ok(boolean,可选):路径不存在时是否忽略。默认值为 false

行为说明:

  • 文件和符号链接无需 recursive 即可删除。
  • 目录在非空时需要设置 recursive = true
  • 未知选项名或非法选项值类型都会抛出错误。

示例:

ptool.fs.remove("tmp/hello.txt")
ptool.fs.remove("tmp/cache", { recursive = true })
ptool.fs.remove("tmp/missing.txt", { missing_ok = true })

ptool.fs.copy

v0.1.0-alpha.4 - 引入。 v0.9.0 - 本地到本地复制现已支持目录,以及文件复制时的目标目录语义。

ptool.fs.copy(src, dst[, options]) 在本地路径之间,或在本地路径与 SSH 远程路径之间复制文件或目录。

  • src(string|remote path,必填):源路径。本地路径使用字符串。远程路径使用由 conn:path(...) 创建的值。
  • dst(string|remote path,必填):目标路径。本地路径使用字符串。远程路径使用由 conn:path(...) 创建的值。
  • options(table,选填):传输选项。
  • 返回:包含以下字段的表:
    • bytes(integer):复制的常规文件字节数。复制目录时,这是所有已复制文件大小之和。
    • from(string):源路径。
    • to(string):目标路径。

支持的传输选项:

  • parents(boolean,选填):在需要时为最终的本地或远程目标路径创建父目录。默认为 false
  • overwrite(boolean,选填):是否允许替换或复用已存在的目标文件或最终目标目录。默认为 true
  • echo(boolean,选填):是否在执行前打印这次传输。默认为 false

行为说明:

  • 本地到本地复制同时支持文件和目录。
  • src 是文件且 dst 是文件路径时,文件会被复制到该精确路径。
  • src 是文件且 dst 已存在并且是目录时,文件会以源文件 basename 复制到该目录下。
  • src 是文件且 dst/\\ 结尾时,dst 会被视为目标目录路径,复制后的文件会保留源文件 basename。如果该目录尚不存在,可通过 parents = true 创建。
  • src 是目录且 dst 不存在时,dst 会成为目标目录根路径。
  • src 是目录且 dst 已存在并且是目录时,会在其下使用源目录 basename 创建该源目录。
  • overwrite = false 会拒绝已存在的目标文件或最终目标目录。
  • 本地目录复制会拒绝位于源目录内部的目标路径。
  • 本地到远程复制遵循与 conn:upload(...) 相同的目标路径规则。
  • 远程到本地复制遵循与 conn:download(...) 相同的目标路径规则。
  • 不支持远程到远程复制。

示例:

local res = ptool.fs.copy("./dist/app.tar.gz", "./tmp/releases/", {
parents = true,
overwrite = true,
echo = true,
})

print(res.bytes)
print(res.to)

目录示例:

local res = ptool.fs.copy("./dist/assets", "./tmp/releases", {
parents = true,
overwrite = true,
})

print(res.bytes)
print(res.to)

远程示例:

local ssh = ptool.ssh.connect("deploy@example.com")

local res = ptool.fs.copy("./dist/assets", ssh:path("/srv/app/releases"), {
parents = true,
overwrite = true,
echo = true,
})

print(res.bytes)
print(res.to)

ptool.fs.glob

v0.2.0 - 引入。 v0.5.0 - 新增 working_dir 选项。

ptool.fs.glob(pattern[, options]) 使用 Unix 风格 glob 语法匹配文件系统 路径,并按字典序返回命中的路径字符串数组。

  • pattern(string,必填):glob 模式。相对模式会从当前 ptool 运行时目录 解析,因此会受到 ptool.cd(...) 的影响。
  • options(table,可选):glob 选项。支持:
    • working_dir(string,可选):覆盖相对模式解析时使用的基准目录。 相对 working_dir 会从当前 ptool 运行时目录解析。
  • 返回:string[]
  • 隐藏文件和目录只有在对应模式片段显式以 . 开头时才会被匹配。

示例:

ptool.cd("src")

local rust_files = ptool.fs.glob("**/*.rs")
local hidden = ptool.fs.glob("**/.secret/*.txt")
local lua_scripts = ptool.fs.glob("**/*.lua", {
working_dir = "../scripts",
})