文件读写 #

一、文件操作概述 #

Deno提供了丰富的文件操作API,所有文件操作都需要相应的权限(–allow-read、–allow-write)。

二、读取文件 #

2.1 读取文本文件 #

typescript
// 读取整个文件为字符串
const content = await Deno.readTextFile("./hello.txt");
console.log(content);

// 同步读取
const contentSync = Deno.readTextFileSync("./hello.txt");

2.2 读取二进制文件 #

typescript
// 读取为Uint8Array
const data = await Deno.readFile("./image.png");
console.log(data.length);

// 同步读取
const dataSync = Deno.readFileSync("./image.png");

2.3 打开文件读取 #

typescript
// 打开文件获取文件对象
const file = await Deno.open("./hello.txt", { read: true });

// 读取内容
const buffer = new Uint8Array(1024);
const bytesRead = await file.read(buffer);
console.log(new TextDecoder().decode(buffer.subarray(0, bytesRead!)));

// 关闭文件
file.close();

2.4 错误处理 #

typescript
try {
  const content = await Deno.readTextFile("./not-exist.txt");
} catch (error) {
  if (error instanceof Deno.errors.NotFound) {
    console.log("文件不存在");
  } else {
    throw error;
  }
}

三、写入文件 #

3.1 写入文本文件 #

typescript
// 写入文本(覆盖)
await Deno.writeTextFile("./output.txt", "Hello, Deno!");

// 追加文本
await Deno.writeTextFile("./output.txt", "\nNew line", { append: true });

// 同步写入
Deno.writeTextFileSync("./output.txt", "Hello, Deno!");

3.2 写入二进制文件 #

typescript
// 写入Uint8Array
const encoder = new TextEncoder();
const data = encoder.encode("Hello, Deno!");
await Deno.writeFile("./output.bin", data);

// 同步写入
Deno.writeFileSync("./output.bin", data);

3.3 打开文件写入 #

typescript
// 打开文件写入
const file = await Deno.open("./output.txt", {
  write: true,
  create: true,
  truncate: true
});

// 写入数据
const encoder = new TextEncoder();
const data = encoder.encode("Hello, Deno!");
await file.write(data);

// 关闭文件
file.close();

3.4 创建目录 #

typescript
// 创建目录
await Deno.mkdir("./output", { recursive: true });

// 同步创建
Deno.mkdirSync("./output", { recursive: true });

四、文件信息 #

4.1 获取文件状态 #

typescript
const info = await Deno.stat("./hello.txt");

console.log("文件大小:", info.size);
console.log("是否文件:", info.isFile);
console.log("是否目录:", info.isDirectory);
console.log("修改时间:", info.mtime);
console.log("访问时间:", info.atime);
console.log("权限:", info.mode?.toString(8));

4.2 检查文件是否存在 #

typescript
async function exists(path: string): Promise<boolean> {
  try {
    await Deno.stat(path);
    return true;
  } catch (error) {
    if (error instanceof Deno.errors.NotFound) {
      return false;
    }
    throw error;
  }
}

console.log(await exists("./hello.txt"));

五、文件操作 #

5.1 复制文件 #

typescript
// 复制文件
await Deno.copyFile("./source.txt", "./dest.txt");

// 同步复制
Deno.copyFileSync("./source.txt", "./dest.txt");

5.2 重命名/移动文件 #

typescript
// 重命名文件
await Deno.rename("./old.txt", "./new.txt");

// 同步重命名
Deno.renameSync("./old.txt", "./new.txt");

5.3 删除文件 #

typescript
// 删除文件
await Deno.remove("./output.txt");

// 删除目录(递归)
await Deno.remove("./output", { recursive: true });

// 同步删除
Deno.removeSync("./output.txt");

5.4 符号链接 #

typescript
// 创建符号链接
await Deno.symlink("./target.txt", "./link.txt");

// 读取符号链接目标
const target = await Deno.readLink("./link.txt");

// 解析符号链接的真实路径
const realPath = await Deno.realPath("./link.txt");

六、文件权限 #

6.1 修改权限 #

typescript
// 修改文件权限(Unix)
await Deno.chmod("./script.sh", 0o755);

// 同步修改
Deno.chmodSync("./script.sh", 0o755);

6.2 修改所有者 #

typescript
// 修改所有者(需要root权限)
await Deno.chown("./file.txt", 1000, 1000);

// 同步修改
Deno.chownSync("./file.txt", 1000, 1000);

七、实际应用 #

7.1 配置文件管理 #

typescript
interface Config {
  host: string;
  port: number;
  debug: boolean;
}

async function loadConfig(path: string): Promise<Config> {
  try {
    const content = await Deno.readTextFile(path);
    return JSON.parse(content);
  } catch (error) {
    if (error instanceof Deno.errors.NotFound) {
      return { host: "localhost", port: 3000, debug: false };
    }
    throw error;
  }
}

async function saveConfig(path: string, config: Config): Promise<void> {
  await Deno.writeTextFile(path, JSON.stringify(config, null, 2));
}

7.2 日志文件 #

typescript
class Logger {
  private file: Deno.FsFile | null = null;
  
  async open(path: string): Promise<void> {
    this.file = await Deno.open(path, {
      write: true,
      create: true,
      append: true
    });
  }
  
  async log(message: string): Promise<void> {
    if (!this.file) return;
    
    const timestamp = new Date().toISOString();
    const line = `[${timestamp}] ${message}\n`;
    await this.file.write(new TextEncoder().encode(line));
  }
  
  close(): void {
    this.file?.close();
  }
}

const logger = new Logger();
await logger.open("./app.log");
await logger.log("Application started");
logger.close();

7.3 文件监控 #

typescript
async function watchFile(path: string, callback: () => void): Promise<void> {
  const watcher = Deno.watchFs(path);
  
  for await (const event of watcher) {
    if (event.kind === "modify") {
      callback();
    }
  }
}

await watchFile("./config.json", () => {
  console.log("配置文件已修改");
});

八、总结 #

本章学习了:

  • 读取文本和二进制文件
  • 写入文本和二进制文件
  • 获取文件信息
  • 文件操作(复制、重命名、删除)
  • 文件权限管理
  • 实际应用场景

下一章,我们将学习目录操作。

最后更新:2026-03-28