Node.js v8.x 中文文档


目录

fs (文件系统)#

稳定性: 2 - 稳定的

文件 I/O 是对标准 POSIX 函数的简单封装。 通过 require('fs') 使用该模块。 所有的方法都有异步和同步的形式。

异步方法的最后一个参数都是一个回调函数。 传给回调函数的参数取决于具体方法,但回调函数的第一个参数都会保留给异常。 如果操作成功完成,则第一个参数会是 nullundefined

当使用同步方法时,任何异常都会被立即抛出。 可以使用 try/catch 来处理异常,或让异常向上冒泡。

异步方法的例子:

const fs = require('fs');

fs.unlink('/tmp/hello', (err) => {
  if (err) throw err;
  console.log('成功删除 /tmp/hello');
});

同步方法的例子:

const fs = require('fs');

fs.unlinkSync('/tmp/hello');
console.log('成功删除 /tmp/hello');

异步的方法不能保证执行顺序。 所以下面的例子可能会出错:

fs.rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  console.log('重命名完成');
});
fs.stat('/tmp/world', (err, stats) => {
  if (err) throw err;
  console.log(`文件属性: ${JSON.stringify(stats)}`);
});

fs.stat 可能在 fs.rename 之前执行。 正确的方法是把回调链起来。

fs.rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  fs.stat('/tmp/world', (err, stats) => {
    if (err) throw err;
    console.log(`文件属性: ${JSON.stringify(stats)}`);
  });
});

在繁忙的进程中,建议使用异步的方法。 同步的方法会阻塞整个进程,直到完成(停止所有连接)。

可以使用文件名的相对路径。 路径是相对 process.cwd() 的。

大多数 fs 函数可以省略回调函数,在这种情况下,会使用默认的回调函数。 若要追踪最初的调用点,可设置 NODE_DEBUG 环境变量:

注意:不建议省略异步方法的回调函数,未来的版本可能会导致抛出错误。

$ cat script.js
function bad() {
  require('fs').readFile('/');
}
bad();

$ env NODE_DEBUG=fs node script.js
fs.js:88
        throw backtrace;
        ^
Error: EISDIR: illegal operation on a directory, read
    <stack trace.>

注意:在 Windows 上 Node.js 遵循单驱动器工作目录的理念。 当使用驱动器路径且不带反斜杠时就能体验到该特征。 例如,fs.readdirSync('c:\\') 可能返回与 fs.readdirSync('c:') 不同的结果。 详见 MSDN 路径文档

注意: 在 Windows 上,使用 w 选项(通过 fs.openfs.writeFile) 打开已有隐藏文件将会失败,错误信息为 EPERM 。已有隐藏文件可以通过 r+ 选项打开。调用 fs.ftruncate 可以用来重置文件内容。

线程池的使用#

注意: 在所有的文件系统 API 中,除了 fs.FSWatcher() 和那些显式同步之外都可以使用 libuv 的线程池,这对于某些应用程序可能会产生出乎意料问题和负面的性能影响,相关详细信息,请参阅 UV_THREADPOOL_SIZE 文档。

WHATWG URL object support#

稳定性: 1 - 实验性的

对于大多数 fs 模块的函数, path 或者 filename 参数可以当作一个 WHATWG URL 对象传入。 只有 URL 对象使用被支持的 file: 协议。

const fs = require('fs');
const { URL } = require('url');
const fileUrl = new URL('file:///tmp/hello');

fs.readFileSync(fileUrl);

注意file: URLS 必须是绝对路径。

使用 WHATWG URL 对象在不同的平台会有特定的行为。

在 Windows 上, 携带主机名的 file: URLs 被转换为 UNC 路径, 而有硬盘盘符的 file: URLs 会被转换成 本地绝对路径。既没有主机名,也没有盘符的 file: URLs 在转换时会抛出错误。

// 在Windows上 :

// - WHATWG 标准的 URLs 会将携带主机名的 file: 转换为 UNC 路径
// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file
fs.readFileSync(new URL('file://hostname/p/a/t/h/file'));

// - WHATWG 标准的 URLs 会将携带本地磁盘盘符的 file: 转换为 绝对路径
// file:///C:/tmp/hello => C:\tmp\hello
fs.readFileSync(new URL('file:///C:/tmp/hello'));

// - WHATWG 标准的 URLs 在转换内容时,如果不携带主机名,则必须包含本地磁盘盘符
fs.readFileSync(new URL('file:///notdriveletter/p/a/t/h/file'));
fs.readFileSync(new URL('file:///c/p/a/t/h/file'));
// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute

注意: 携带盘符的 file: URLs 必须使用 : 作为盘符后的分隔符。使用其他符号会抛出错误。

在其他所有的平台上, 都不支持携带主机名的 file: URLs,且会抛出错误。

// 在其他平台上:

// - WHATWG 标准的 URLs 不支持携带 hostname 的 file: 进行转换
// file://hostname/p/a/t/h/file => throw!
fs.readFileSync(new URL('file://hostname/p/a/t/h/file'));
// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute

// - WHATWG 标准的 URLs 会将 file: 转换绝对路径 
// file:///tmp/hello => /tmp/hello
fs.readFileSync(new URL('file:///tmp/hello'));

file: URL 包含已经编码的斜线符号会在所有平台抛出错误。

// 在 Windows 上
fs.readFileSync(new URL('file:///C:/p/a/t/h/%2F'));
fs.readFileSync(new URL('file:///C:/p/a/t/h/%2f'));
/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
\ or / characters */

// 在 POSIX 上
fs.readFileSync(new URL('file:///p/a/t/h/%2F'));
fs.readFileSync(new URL('file:///p/a/t/h/%2f'));
/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
/ characters */

在 Windows 上, 携带已编码的反斜线 file: URLs 在编码是会抛出错误。

// 在 Windows 上
fs.readFileSync(new URL('file:///C:/path/%5C'));
fs.readFileSync(new URL('file:///C:/path/%5c'));
/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
\ or / characters */

Buffer API#

fs 函数支持传递和接收字符串路径与 Buffer 路径。 后者的目的是使其可以在允许非 UTF-8 文件名的文件系统中工作。 对于大多数普通用途,使用 Buffer 路径是不必要的,因为字符串 API 会自动与 UTF-8 相互转换。

注意,在某些文件系统(如 NTFS 和 HFS+),文件名总是被编码为 UTF-8。 在这些文件系统中,传入非 UTF-8 编码的 Buffer 到 fs 函数将无法像预期那样工作。

fs.FSWatcher 类#

fs.watch() 返回的对象是该类型。

提供给 fs.watch()listener 回调会接收返回的 FSWatcher 的 change 事件。

该对象本身可触发以下事件:

'change' 事件#

  • eventType <string> fs 变化的类型
  • filename <string> | <Buffer> 变化的文件名(如果是相关的/可用的)

当一个被监视的目录或文件有变化时触发。 详见 fs.watch()

filename 参数可能不会被提供,这依赖于操作系统支持。 如果提供了 filename,则若 fs.watch() 被调用时 encoding 选项被设置为 'buffer' 则它会是一个 Buffer,否则 filename 是一个字符串。

// 例子,处理 fs.watch 监听器
fs.watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {
  if (filename) {
    console.log(filename);
    // 输出: <Buffer ...>
  }
});

'error' 事件#

当发生错误时触发。

watcher.close()#

停止监听 fs.FSWatcher 的变化。

fs.ReadStream 类#

ReadStream 是一个可读流

'close' 事件#

ReadStream 底层的文件描述符被关闭时触发。

'open' 事件#

  • fd <integer> 被 ReadStream 使用的整数文件描述符。

当 ReadStream 的文件被打开时触发。

readStream.bytesRead#

已读取的字节数。

readStream.path#

流正在读取的文件的路径,指定在 fs.createReadStream() 的第一个参数。 如果 path 传入的是一个字符串,则 readStream.path 是一个字符串。 如果 path 传入的是一个 Buffer,则 readStream.path 是一个 Buffer

fs.Stats 类#

fs.stat()fs.lstat()fs.fstat() 及其同步版本返回的对象都是该类型。

  • stats.isFile()
  • stats.isDirectory()
  • stats.isBlockDevice()
  • stats.isCharacterDevice()
  • stats.isSymbolicLink() (仅对 fs.lstat() 有效)
  • stats.isFIFO()
  • stats.isSocket()

对于一个普通文件,util.inspect(stats) 会返回一个类似如下的字符串:

Stats {
  dev: 2114,
  ino: 48064969,
  mode: 33188,
  nlink: 1,
  uid: 85,
  gid: 100,
  rdev: 0,
  size: 527,
  blksize: 4096,
  blocks: 8,
  atimeMs: 1318289051000.1,
  mtimeMs: 1318289051000.1,
  ctimeMs: 1318289051000.1,
  birthtimeMs: 1318289051000.1,
  atime: Mon, 10 Oct 2011 23:24:11 GMT,
  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }

注意atimeMsmtimeMsctimeMsbirthtimeMs 是以单位为毫秒保存相对应时间的数字 numbers。 他们的精度由所在的平台决定。atimemtimectime 以及 birthtime 是表示各个时间的日期对象 [Date][MDN-Date]Date 与数值并没有关联。对数值进行重新赋值,或者改变 Date 的值,不会反映到相对应的表示中。

Stat 时间值#

stat 对象中的时间有以下语义:

  • atime "访问时间" - 文件数据最近被访问的时间。 会被 mknod(2)utimes(2)read(2) 系统调用改变。
  • mtime "修改时间" - 文件数据最近被修改的时间。 会被 mknod(2)utimes(2)write(2) 系统调用改变。
  • ctime "变化时间" - 文件状态最近更改的时间(修改索引节点数据) 会被 chmod(2)chown(2)link(2)mknod(2)rename(2)unlink(2)utimes(2)read(2)write(2) 系统调用改变。
  • birthtime "创建时间" - 文件创建的时间。 当文件被创建时设定一次。 在创建时间不可用的文件系统中,该字段可能被替代为 ctime1970-01-01T00:00Z(如 Unix 的纪元时间戳 0)。 注意,该值在此情况下可能会大于 atimemtime。 在 Darwin 和其它的 FreeBSD 衍生系统中,如果 atime 被使用 utimes(2) 系统调用显式地设置为一个比当前 birthtime 更早的值,也会有这种情况。

在 Node.js v0.12 之前的版本中,ctime 在 Windows 系统中保存 birthtime。 注意,在 v0.12 中,ctime 不是“创建时间”,并且在 Unix 系统中,它从来都不是。

fs.WriteStream 类#

WriteStream 一个可写流

'close' 事件#

WriteStream 底层的文件描述符被关闭时触发。

'open' 事件#

  • fd <integer> 被 WriteStream 使用的整数文件描述符。

当 WriteStream 的文件被打开时触发。

writeStream.bytesWritten#

已写入的字节数。 不包括仍在排队等待写入的数据。

writeStream.path#

流正在写入的文件的路径,指定在 fs.createWriteStream() 的第一个参数。 如果 path 传入的是一个字符串,则 writeStream.path 是一个字符串。 如果 path 传入的是一个 Buffer,则 writeStream.path 是一个 Buffer

fs.access(path[, mode], callback)#

测试 path 指定的文件或目录的用户权限。 mode 是一个可选的整数,指定要执行的可访问性检查。 以下常量定义了 mode 的可能值。 可以创建由两个或更多个值的位或组成的掩码(例如 fs.constants.W_OK | fs.constants.R_OK)。

  • fs.constants.F_OK - path 文件对调用进程可见。 这在确定文件是否存在时很有用,但不涉及 rwx 权限。 如果没指定 mode,则默认为该值。
  • fs.constants.R_OK - path 文件可被调用进程读取。
  • fs.constants.W_OK - path 文件可被调用进程写入。
  • fs.constants.X_OK - path 文件可被调用进程执行。 对 Windows 系统没作用(相当于 fs.constants.F_OK)。

最后一个参数 callback 是一个回调函数,会带有一个可能的错误参数被调用。 如果可访问性检查有任何的失败,则错误参数会是一个 Error 对象。 下面的例子会检查 /etc/passwd 文件是否可以被当前进程读取和写入。

fs.access('/etc/passwd', fs.constants.R_OK | fs.constants.W_OK, (err) => {
  console.log(err ? 'no access!' : 'can read/write');
});

不建议在调用 fs.open()fs.readFile()fs.writeFile() 之前使用 fs.access() 检查一个文件的可访问性。 如此处理会造成紊乱情况,因为其他进程可能在两个调用之间改变该文件的状态。 作为替代,用户代码应该直接打开/读取/写入文件,当文件无法访问时再处理错误。

例子:

写入(不推荐)

fs.access('myfile', (err) => {
  if (!err) {
    console.error('myfile already exists');
    return;
  }

  fs.open('myfile', 'wx', (err, fd) => {
    if (err) throw err;
    writeMyData(fd);
  });
});

写入(推荐)

fs.open('myfile', 'wx', (err, fd) => {
  if (err) {
    if (err.code === 'EEXIST') {
      console.error('myfile already exists');
      return;
    }

    throw err;
  }

  writeMyData(fd);
});

读取(不推荐)

fs.access('myfile', (err) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.error('myfile does not exist');
      return;
    }

    throw err;
  }

  fs.open('myfile', 'r', (err, fd) => {
    if (err) throw err;
    readMyData(fd);
  });
});

读取(推荐)

fs.open('myfile', 'r', (err, fd) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.error('myfile does not exist');
      return;
    }

    throw err;
  }

  readMyData(fd);
});

以上不推荐的例子检查可访问性之后再使用文件; 推荐的例子更好,因为它们直接使用文件并处理任何错误。

通常,仅在文件不会被直接使用时才检查一个文件的可访问性,例如当它的可访问性是来自另一个进程的信号。

fs.accessSync(path[, mode])#

同步地测试 path 指定的文件或目录的用户权限。 mode 是一个可选的整数,指定要执行的可访问性检查。 以下常量定义了 mode 的可能值。 可以创建由两个或更多个值的位或组成的掩码(例如 fs.constants.W_OK | fs.constants.R_OK)。

  • fs.constants.F_OK - path 文件对调用进程可见。 这在确定文件是否存在时很有用,但不涉及 rwx 权限。 如果没指定 mode ,则默认为该值
  • fs.constants.R_OK - path 文件可被调用进程读取。
  • fs.constants.W_OK - path 文件可被调用进程写入。
  • fs.constants.X_OK - path 文件可被调用进程执行。 对 Windows 系统没作用(相当于 fs.constants.F_OK)。

如果可访问性检查有任何的失败,则错误参数会是一个 Error 对象。 否则返回 undefined

try {
  fs.accessSync('etc/passwd', fs.constants.R_OK | fs.constants.W_OK);
  console.log('can read/write');
} catch (err) {
  console.error('no access!');
}

fs.appendFile(file, data[, options], callback)#

异步地追加数据到一个文件,如果文件不存在则创建文件。 data 可以是一个字符串或 Buffer

例子:

fs.appendFile('message.txt', 'data to append', (err) => {
  if (err) throw err;
  console.log('The "data to append" was appended to file!');
});

如果 options 是一个字符串,则它指定了字符编码。例如:

fs.appendFile('message.txt', 'data to append', 'utf8', callback);

file 可能是一个被打开用来追加数据的数字文件描述符(通过 fs.open() 或者 fs.openSync())。这样的文件描述符将不会被自动关闭。

fs.open('message.txt', 'a', (err, fd) => {
  if (err) throw err;
  fs.appendFile(fd, 'data to append', 'utf8', (err) => {
    fs.close(fd, (err) => {
      if (err) throw err;
    });
    if (err) throw err;
  });
});

fs.appendFileSync(file, data[, options])#

Synchronously append data to a file, creating the file if it does not yet exist. data can be a string or a Buffer.

Example:

try {
  fs.appendFileSync('message.txt', 'data to append');
  console.log('The "data to append" was appended to file!');
} catch (err) {
  /* Handle the error */
}

If options is a string, then it specifies the encoding. Example:

fs.appendFileSync('message.txt', 'data to append', 'utf8');

The file may be specified as a numeric file descriptor that has been opened for appending (using fs.open() or fs.openSync()). The file descriptor will not be closed automatically.

let fd;

try {
  fd = fs.openSync('message.txt', 'a');
  fs.appendFileSync(fd, 'data to append', 'utf8');
} catch (err) {
  /* Handle the error */
} finally {
  if (fd !== undefined)
    fs.closeSync(fd);
}

fs.chmod(path, mode, callback)#

异步地改变文件的权限。 完成回调只有一个可能的异常参数。

详见 chmod(2)

File modes#

mode 参数会在 fs.chmod()fs.chmodSync()方法中用到,它是用下面的常量进行逻辑或(logical OR)操作后的数字掩码:

Constant Octal Description
fs.constants.S_IRUSR 0o400 read by owner
fs.constants.S_IWUSR 0o200 write by owner
fs.constants.S_IXUSR 0o100 execute/search by owner
fs.constants.S_IRGRP 0o40 read by group
fs.constants.S_IWGRP 0o20 write by group
fs.constants.S_IXGRP 0o10 execute/search by group
fs.constants.S_IROTH 0o4 read by others
fs.constants.S_IWOTH 0o2 write by others
fs.constants.S_IXOTH 0o1 execute/search by others

一个构造 mode 的更简单的方式是使用3位八进制串(比如,765)。最左侧的数字(例中的7)代表了文件所有者的权限。中间一位(例中的6)代表了组的权限。最右侧的数字(例中的5)代表其他人的权限。 A

Number Description
7 read, write, and execute
6 read and write
5 read and execute
4 read only
3 write and execute
2 write only
1 execute only
0 no permission

举个例子,八进制值 0o765 表示:

  • 文件所有者可以进行读、写和执行。
  • 文件所属组可以读和写。
  • 其他人可以对文件进行读和执行。

fs.chmodSync(path, mode)#

同步地改变文件的权限。 返回 undefinedfs.chmod()的同步版本。

详见 chmod(2)

fs.chown(path, uid, gid, callback)#

异步地改变文件的所有者和群组。 完成回调只有一个可能的异常参数。

详见 chown(2)

fs.chownSync(path, uid, gid)#

同步地改变文件的所有者和群组。 返回 undefinedfs.chown() 的同步版本。

详见 chown(2)

fs.close(fd, callback)#

异步的 close(2)。 完成回调只有一个可能的异常参数。

fs.closeSync(fd)#

同步的 close(2)。返回 undefined

fs.constants#

返回一个包含常用文件系统操作的常量的对象。 具体的常量定义在 FS Constants 中描述。

fs.copyFile(src, dest[, flags], callback)#

异步的将 src 拷贝到 dest。Asynchronously copies src to dest. 默认情况下,如果 dest 已经存在会被覆盖。回调函数没有给出除了异常以外的参数。Node.js 不能保证拷贝操作的原子性。如果目标文件打开后出现错误,Node.js 将尝试删除它。

flags 是一个可选的整数,用于指定行为的拷贝操作。唯一支持的 flag 是 fs.constants.COPYFILE_EXCL ,如果 dest 已经存在,则会导致拷贝操作失败。

例:

const fs = require('fs');

// 默认情况下,destination.txt 将创建或覆盖
fs.copyFile('source.txt', 'destination.txt', (err) => {
  if (err) throw err;
  console.log('source.txt was copied to destination.txt');
});

如果第三个参数是数字,那么肯定是 flags,代码如下所示:

const fs = require('fs');
const { COPYFILE_EXCL } = fs.constants;

// 使用 COPYFILE_EXCL ,如果 destination.txt 文件存在,操作将失败。
fs.copyFile('source.txt', 'destination.txt', COPYFILE_EXCL, callback);

fs.copyFileSync(src, dest[, flags])#

同步的将 src 拷贝到 dest。默认情况下,如果 dest 已经存在会被覆盖。返回值是 undefined。Node.js 不能保证拷贝操作的原子性。如果目标文件打开后出现错误,Node.js 将尝试删除它。

flags 是一个可选的整数,用于指定行为的拷贝操作。唯一支持的 flag 是 fs.constants.COPYFILE_EXCL ,如果 dest 已经存在,则会导致拷贝操作失败。

例:

const fs = require('fs');

// 默认情况下,destination.txt 将创建或覆盖
fs.copyFileSync('source.txt', 'destination.txt');
console.log('source.txt was copied to destination.txt');

如果第三个参数是数字,那么肯定是 flags,代码如下所示:

const fs = require('fs');
const { COPYFILE_EXCL } = fs.constants;

// 使用 COPYFILE_EXCL ,如果 destination.txt 文件存在,操作将失败。
fs.copyFileSync('source.txt', 'destination.txt', COPYFILE_EXCL);

fs.createReadStream(path[, options])#

返回一个新建的 ReadStream 对象(详见可读流)。

不同于在一个可读流上设置的 highWaterMark 默认值(16 kb),该方法在相同参数下返回的流具有 64 kb 的默认值。

options 是一个带有以下默认值的对象或字符串:

const defaults = {
  flags: 'r',
  encoding: null,
  fd: null,
  mode: 0o666,
  autoClose: true,
  highWaterMark: 64 * 1024
};

options 可以包括 startend 值,使其可以从文件读取一定范围的字节而不是整个文件。 startend 都是包括在内的,并且起始值是 0。 如果指定了 fdstart 不传或为 undefined,则 fs.createReadStream() 从当前文件位置按顺序地读取。 encoding 可以是任何可以被 Buffer 接受的值。

如果指定了 fd,则 ReadStream 会忽略 path 参数并且会使用指定的文件描述符。 这意味着不会触发 'open' 事件。 注意,fd 应该是阻塞的;非阻塞的 fd 们应该传给 net.Socket

如果 autoClosefalse,则文件描述符不会被关闭,即使有错误。 应用程序需要负责关闭它,并且确保没有文件描述符泄漏。 如果 autoClose 被设置为 true(默认),则在 errorend 时,文件描述符会被自动关闭。

mode 用于设置文件模式(权限和粘结位),但仅限创建文件时。

例子,从一个 100 字节长的文件中读取最后 10 个字节:

fs.createReadStream('sample.txt', { start: 90, end: 99 });

如果 options 是一个字符串,则它指定了字符编码。

fs.createWriteStream(path[, options])#

返回一个新建的 WriteStream 对象(详见可写流)。

options 是一个带有以下默认值的对象或字符串:

const defaults = {
  flags: 'w',
  encoding: 'utf8',
  fd: null,
  mode: 0o666,
  autoClose: true
};

options 也可以包括一个 start 选项,使其可以写入数据到文件某个位置。 如果是修改一个文件而不是覆盖它,则需要flags 模式为 r+ 而不是默认的 w 模式。 encoding 可以是任何可以被 Buffer 接受的值。

如果 autoClose 被设置为 true(默认),则在 errorend 时,文件描述符会被自动关闭。 如果 autoClosefalse,则文件描述符不会被关闭,即使有错误。 应用程序需要负责关闭它,并且确保没有文件描述符泄漏。

类似 ReadStream,如果指定了 fd,则 WriteStream 会忽略 path 参数并且会使用指定的文件描述符。 这意味着不会触发 'open' 事件。 注意,fd 应该是阻塞的;非阻塞的 fd 们应该传给 net.Socket

如果 options 是一个字符串,则它指定了字符编码。

fs.exists(path, callback)#

稳定性: 0 - 废弃的: 使用 fs.stat()fs.access() 代替。

通过检查文件系统来测试给定的路径是否存在。然后使用 true 或 false 为参数调用 callback。例子:

fs.exists('/etc/passwd', (exists) => {
  console.log(exists ? 'it\'s there' : 'no passwd!');
});

注意此回调的参数和其他 Node.js 回调的参数不一致。 通常,Node.js 回调的第一个参数是 err, 接下来是一些其他可选参数。 fs.exists() 只有一个布尔类型的参数。这也是为什么推荐使用 fs.access() 代替 fs.exists()

不推荐在调用 fs.openfs.readFile()fs.writeFile() 之前使用 fs.exists() 检测文件是否存在。这样做会引起竞争条件,因为在两次调用之间,其他进程可能修改文件。作为替代,用户应该直接开/读取/写入文件,当文件不存在时再处理错误。

例子:

write (不推荐)

fs.exists('myfile', (exists) => {
  if (exists) {
    console.error('myfile already exists');
  } else {
    fs.open('myfile', 'wx', (err, fd) => {
      if (err) throw err;
      writeMyData(fd);
    });
  }
});

write (推荐)

fs.open('myfile', 'wx', (err, fd) => {
  if (err) {
    if (err.code === 'EEXIST') {
      console.error('myfile already exists');
      return;
    }

    throw err;
  }

  writeMyData(fd);
});

read (不推荐)

fs.exists('myfile', (exists) => {
  if (exists) {
    fs.open('myfile', 'r', (err, fd) => {
      readMyData(fd);
    });
  } else {
    console.error('myfile does not exist');
  }
});

read (推荐)

fs.open('myfile', 'r', (err, fd) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.error('myfile does not exist');
      return;
    }

    throw err;
  }

  readMyData(fd);
});

上面这些 不推荐 的例子先检测文件是否存在再使用文件;推荐 的例子更好因为它直接使用文件并处理任何错误。

通常,仅在文件不会被直接使用时才检查一个文件的可访问性,例如当它的可访问性是来自另一个进程的信号。

fs.existsSync(path)#

fs.exists() 的同步版本。 如果路径存在,则返回 true,否则返回 false

注意,虽然 fs.exists() 是废弃的,但 fs.existsSync() 不是。 (fs.exists() 的回调接收的参数与其他 Node.js 回调不一致,fs.existsSync() 不使用回调。)

fs.fchmod(fd, mode, callback)#

异步的 fchmod(2)。 完成回调只有一个可能的异常参数。

fs.fchmodSync(fd, mode)#

同步的 fchmod(2)。返回 undefined

fs.fchown(fd, uid, gid, callback)#

异步的 fchown(2)。 完成回调只有一个可能的异常参数。

fs.fchownSync(fd, uid, gid)#

同步的 fchown(2)。返回 undefined

fs.fdatasync(fd, callback)#

异步的 fdatasync(2)。 完成回调只有一个可能的异常参数。

fs.fdatasyncSync(fd)#

同步的 fdatasync(2)。返回 undefined

fs.fstat(fd, callback)#

异步的 fstat(2)。 回调获得两个参数 (err, stats),其中 stats 是一个 fs.Stats 对象。 fstat()stat() 类似,除了文件是通过文件描述符 fd 指定的。

fs.fstatSync(fd)#

同步的 fstat(2)。返回一个 fs.Stats 实例。

fs.fsync(fd, callback)#

异步的 fsync(2)。 完成回调只有一个可能的异常参数。

fs.fsyncSync(fd)#

同步的 fsync(2)。返回 undefined

fs.ftruncate(fd[, len], callback)#

异步的 ftruncate(2)。 完成回调只有一个可能的异常参数。

如果文件描述符指向的文件大于 len 个字节,则只有前面 len 个字节会保留在文件中。

例子,下面的程序会只保留文件前4个字节。

console.log(fs.readFileSync('temp.txt', 'utf8'));
// 输出: Node.js

// 获取要截断的文件的文件描述符
const fd = fs.openSync('temp.txt', 'r+');

// 截断文件至前4个字节
fs.ftruncate(fd, 4, (err) => {
  assert.ifError(err);
  console.log(fs.readFileSync('temp.txt', 'utf8'));
});
// 输出: Node

如果前面的文件小于 len 个字节,则扩展文件,且扩展的部分用空字节('\0')填充。例子:

console.log(fs.readFileSync('temp.txt', 'utf8'));
// 输出: Node.js

// 获取要截断的文件的文件描述符
const fd = fs.openSync('temp.txt', 'r+');

// 截断文件至前10个字节,但实际大小是7个字节
fs.ftruncate(fd, 10, (err) => {
  assert.ifError(err);
  console.log(fs.readFileSync('temp.txt'));
});
// 输出: <Buffer 4e 6f 64 65 2e 6a 73 00 00 00>
// ('Node.js\0\0\0' in UTF8)

最后3个字节是空字节('\0'),用于补充超出的截断。

fs.ftruncateSync(fd[, len])#

同步的 ftruncate(2)。返回 undefined

fs.futimes(fd, atime, mtime, callback)#

改变由所提供的文件描述符所指向的对象的文件系统时间戳。详见 fs.utimes()

请注意: 该函数不支持AIX 7.1以下版本,在AIX 7.1以下版本会返回UV_ENOSYS错误。

fs.futimesSync(fd, atime, mtime)#

fs.futimes() 的同步版本。返回 undefined

fs.lchmod(path, mode, callback)#

异步的 lchmod(2)。 完成回调只有一个可能的异常参数。

只在 macOS 有效。

fs.lchmodSync(path, mode)#

同步的 lchmod(2)。返回 undefined

fs.lchown(path, uid, gid, callback)#

异步的 lchown(2)。 完成回调只有一个可能的异常参数。

fs.lchownSync(path, uid, gid)#

同步的 lchown(2)。返回 undefined

fs.link(existingPath, newPath, callback)#

异步的 link(2)。 完成回调只有一个可能的异常参数。

fs.linkSync(existingPath, newPath)#

同步的 link(2)。返回 undefined

fs.lstat(path, callback)#

异步的 lstat(2)。 回调获得两个参数 (err, stats),其中 stats 是一个 fs.Stats 对象。 lstat()stat() 类似,除非 path 是一个符号链接,则自身就是该链接,它指向的并不是文件。

fs.lstatSync(path)#

同步的 lstat(2)。返回一个 fs.Stats 实例。

fs.mkdir(path[, mode], callback)#

异步地创建目录。 完成回调只有一个可能的异常参数。 mode 默认为 0o777

详见 mkdir(2)

fs.mkdirSync(path[, mode])#

同步地创建目录。 返回 undefinedfs.mkdir() 的同步版本。

详见 mkdir(2)

fs.mkdtemp(prefix[, options], callback)#

创建一个唯一的临时目录。

生成六位随机字符附加到一个要求的 prefix 后面,然后创建一个唯一的临时目录。

创建的目录路径会作为字符串传给回调的第二个参数。

可选的 options 参数可以是一个字符串并指定一个字符编码,或是一个对象且由一个 encoding 属性指定使用的字符编码。

例子:

fs.mkdtemp(path.join(os.tmpdir(), 'foo-'), (err, folder) => {
  if (err) throw err;
  console.log(folder);
  // 输出: /tmp/foo-itXde2 or C:\Users\...\AppData\Local\Temp\foo-itXde2
});

注意fs.mkdtemp() 方法会直接附加六位随机选择的字符串到 prefix 字符串。 例如,指定一个目录 /tmp,如果目的是要在 /tmp 里创建一个临时目录,则 prefix 必须 以一个指定平台的路径分隔符(require('path').sep)结尾。

// 新建的临时目录的父目录
const tmpDir = os.tmpdir();

// 该方法是 *错误的*:
fs.mkdtemp(tmpDir, (err, folder) => {
  if (err) throw err;
  console.log(folder);
  // 会输出类似于 `/tmpabc123`。
  // 注意,一个新的临时目录会被创建在文件系统的根目录,而不是在 /tmp 目录里。
});

// 该方法是 *正确的*:
const { sep } = require('path');
fs.mkdtemp(`${tmpDir}${sep}`, (err, folder) => {
  if (err) throw err;
  console.log(folder);
  // 会输出类似于 `/tmp/abc123`。
  // 一个新的临时目录会被创建在 /tmp 目录里。
});

fs.mkdtempSync(prefix[, options])#

fs.mkdtemp() 的同步版本。 返回创建的目录的路径。

可选的 options 参数可以是一个字符串并指定一个字符编码,或是一个对象且由一个 encoding 属性指定使用的字符编码。

fs.open(path, flags[, mode], callback)#

异步地打开文件。详见 open(2)flags 可以是:

  • 'r' - 以读取模式打开文件。如果文件不存在则发生异常。

  • 'r+' - 以读写模式打开文件。如果文件不存在则发生异常。

  • 'rs+' - 以同步读写模式打开文件。命令操作系统绕过本地文件系统缓存。

    这对 NFS 挂载模式下打开文件很有用,因为它可以让你跳过潜在的旧本地缓存。 它对 I/O 的性能有明显的影响,所以除非需要,否则不要使用此标志。

    注意,这不会使 fs.open() 进入同步阻塞调用。 如果那是你想要的,则应该使用 fs.openSync()

  • 'w' - 以写入模式打开文件。文件会被创建(如果文件不存在)或截断(如果文件存在)。

  • 'wx' - 类似 'w',但如果 path 存在,则失败。

  • 'w+' - 以读写模式打开文件。文件会被创建(如果文件不存在)或截断(如果文件存在)。

  • 'wx+' - 类似 'w+',但如果 path 存在,则失败。

  • 'a' - 以追加模式打开文件。如果文件不存在,则会被创建。

  • 'ax' - 类似于 'a',但如果 path 存在,则失败。

  • 'a+' - 以读取和追加模式打开文件。如果文件不存在,则会被创建。

  • 'ax+' - 类似于 'a+',但如果 path 存在,则失败。

mode 可设置文件模式(权限和 sticky 位),但只有当文件被创建时才有效。默认为 0o666,可读写。

该回调有两个参数 (err, fd)

特有的标志 'x'(在 open(2) 中的 O_EXCL 标志)确保 path 是新创建的。 在 POSIX 操作系统中,path 会被视为存在,即使是一个链接到一个不存在的文件的符号。 该特有的标志有可能在网络文件系统中无法使用。

flags 也可以是一个数字,[open(2)] 文档中有描述; 常用的常量可从 fs.constants 获取。 在 Windows 系统中,标志会被转换为与它等同的替代者,例如,O_WRONLY 转换为 FILE_GENERIC_WRITE、或 O_EXCL|O_CREAT 转换为 CREATE_NEW,通过 CreateFileW 接受。

在 Linux 中,当文件以追加模式打开时,定位的写入不起作用。 内核会忽略位置参数,并总是附加数据到文件的末尾。

注意:fs.open() 某些标志的行为是与平台相关的。 因此,在 macOS 和 Linux 下用 'a+' 标志打开一个目录(见下面的例子),会返回一个错误。 与此相反,在 Windows 和 FreeBSD,则会返回一个文件描述符。

// macOS 与 Linux
fs.open('<directory>', 'a+', (err, fd) => {
  // => [Error: EISDIR: illegal operation on a directory, open <directory>]
});

// Windows 与 FreeBSD
fs.open('<directory>', 'a+', (err, fd) => {
  // => null, <fd>
});

有些字符 (< > : " / \ | ? *) 在Windows下保留,通过命名文件、路径和命名空间来记录。 在NTFS下,如果文件名包含冒号,Node.js 将打开一个文件系统流, 具体描述在 MSDN页

许多函数也是基于 fs.open() 拥有这样的效果。例: fs.writeFile(), fs.readFile(), 等。

fs.openSync(path, flags[, mode])#

fs.open() 的同步版本。 返回一个表示文件描述符的整数。

fs.read(fd, buffer, offset, length, position, callback)#

fd 指定的文件中读取数据。

buffer 是数据将被写入到的 buffer。

offset 是 buffer 中开始写入的偏移量。

length 是一个整数,指定要读取的字节数。

position 指定从文件中开始读取的位置。 如果 positionnull,则数据从当前文件读取位置开始读取,且文件读取位置会被更新。 如果 position 为一个整数,则文件读取位置保持不变。

回调有三个参数 (err, bytesRead, buffer)

如果调用该方法的 util.promisify() 版本,将会返回一个包含 bytesReadbuffer 属性的 Promise。

fs.readdir(path[, options], callback)#

异步的 readdir(3)。 读取一个目录的内容。 回调有两个参数 (err, files),其中 files 是目录中不包括 '.''..' 的文件名的数组。

可选的 options 参数用于传入回调的文件名,它可以是一个字符串并指定一个字符编码,或是一个对象且由一个 encoding 属性指定使用的字符编码。 如果 encoding 设为 'buffer',则返回的文件名会被作为 Buffer 对象传入。 注意: 'path' 的路径是以当前文件为基准进行查找的,而不是运行的时候的相对路径

fs.readdirSync(path[, options])#

同步的 readdir(3). 返回一个不包括 '.''..' 的文件名的数组。

可选的 options 参数用于传入回调的文件名,它可以是一个字符串并指定一个字符编码,或是一个对象且由一个 encoding 属性指定使用的字符编码。 如果 encoding 设为 'buffer',则返回的文件名会被作为 Buffer 对象传入。

fs.readFile(path[, options], callback)#

异步地读取一个文件的全部内容。 例子:

fs.readFile('/etc/passwd', (err, data) => {
  if (err) throw err;
  console.log(data);
});

回调有两个参数 (err, data),其中 data 是文件的内容。

如果未指定字符编码,则返回原始的 buffer。

如果 options 是一个字符串,则它指定了字符编码。 例子:

fs.readFile('/etc/passwd', 'utf8', callback);

注意:当 path 是一个目录时,fs.readFile()fs.readFileSync() 的行为与平台有关。 在 macOS、Linux 与 Windows 上,会返回一个错误。 在 FreeBSD 上,会返回目录内容的表示。

// 在 macOS、Linux 与 Windows 上:
fs.readFile('<directory>', (err, data) => {
  // => [Error: EISDIR: illegal operation on a directory, read <directory>]
});

//  在 FreeBSD 上:
fs.readFile('<directory>', (err, data) => {
  // => null, <data>
});

任何指定的文件描述符必须支持读取。

注意:如果一个文件描述符被指定为 path,则它不会被自动关闭。

Note: fs.readFile() reads the entire file in a single threadpool request. To minimize threadpool task length variation, prefer the partitioned APIs fs.read() and fs.createReadStream() when reading files as part of fulfilling a client request.

fs.readFileSync(path[, options])#

fs.readFile() 的同步版本。 返回 path 的内容。

如果指定了 encoding 选项,则该函数返回一个字符串,否则返回一个 buffer。

请注意: 与fs.readFile()相似, 当路径是目录时,fs.readFileSync()的行为是基于平台的。

// macOS, Linux 和 Windows
fs.readFileSync('<directory>');
// => [Error: EISDIR: illegal operation on a directory, read <directory>]

//  FreeBSD
fs.readFileSync('<directory>'); // => null, <data>

fs.readlink(path[, options], callback)#

异步的 readlink(2)。 回调有两个参数 (err, linkString)

可选的 options 参数用于传入回调的链接路径,它可以是一个字符串并指定一个字符编码,或是一个对象且由一个 encoding 属性指定使用的字符编码。 如果 encoding 设为 'buffer',则返回的链接路径会被作为 Buffer 对象传入。

fs.readlinkSync(path[, options])#

同步的 readlink(2)。 返回符号链接的字符串值。

可选的 options 参数用于传入回调的链接路径,它可以是一个字符串并指定一个字符编码,或是一个对象且由一个 encoding 属性指定使用的字符编码。 如果 encoding 设为 'buffer',则返回的链接路径会被作为 Buffer 对象传入。

fs.readSync(fd, buffer, offset, length, position)#

fs.read() 的同步版本。 返回 bytesRead 的数量。

fs.realpath(path[, options], callback)#

异步的 realpath(3)callback 有两个参数 (err, resolvedPath)。 可以使用 process.cwd 解析相对路径。

只支持可转换成 UTF8 字符串的路径。

可选的 options 参数用于传入回调的路径,它可以是一个字符串并指定一个字符编码,或是一个对象且由一个 encoding 属性指定使用的字符编码。 如果 encoding 设为 'buffer',则返回的路径会被作为 Buffer 对象传入。

注意: 如果路径解析到套接字或 pipe ,函数将返回与该对象相关的系统名称。

fs.realpathSync(path[, options])#

同步的 realpath(3)。 返回解析的路径。

只支持可转换成 UTF8 字符串的路径。

可选的 options 参数用于传入回调的路径,它可以是一个字符串并指定一个字符编码,或是一个对象且由一个 encoding 属性指定使用的字符编码。 如果 encoding 设为 'buffer',则返回的路径会被作为 Buffer 对象传入。

注意: 如果 path 解析成一个 socket 或者管道,该函数将返回包含系统相关名称的对象。

fs.rename(oldPath, newPath, callback)#

异步的 rename(2)。 完成回调只有一个可能的异常参数。

fs.renameSync(oldPath, newPath)#

同步的 rename(2)。返回 undefined

fs.rmdir(path, callback)#

异步的 rmdir(2)。 完成回调只有一个可能的异常参数。

请注意: 在文件上(而不是目录上)使用fs.rmdir(),在Windows平台将会导致ENOENT错误,而在POSIX平台将会导致ENOTDIR错误。

fs.rmdirSync(path)#

同步的 rmdir(2)。返回 undefined

请注意: 在文件上(而不是目录上)使用fs.rmdirSync(),在Windows平台将会导致ENOENT错误,而在POSIX平台将会导致ENOTDIR错误。

fs.stat(path, callback)#

异步的 stat(2)。 回调有两个参数 (err, stats) 其中 stats 是一个 fs.Stats 对象。

如果发生错误,则 err.code 会是常见系统错误之一。

不建议在调用 fs.open()fs.readFile()fs.writeFile() 之前使用 fs.stat() 检查一个文件是否存在。 作为替代,用户代码应该直接打开/读取/写入文件,当文件无效时再处理错误。

如果要检查一个文件是否存在且不操作它,推荐使用 fs.access()

fs.statSync(path)#

同步的 stat(2)。 返回一个 fs.Stats 实例。

fs.symlink(target, path[, type], callback)#

异步的 symlink(2)。 完成回调只有一个可能的异常参数。 type 参数可以设为 'dir''file''junction'(默认为 'file'),且仅在 Windows 上有效(在其他平台上忽略)。 注意,Windows 结点要求目标路径是绝对的。 当使用 'junction' 时,target 参数会被自动标准化为绝对路径。

例子:

fs.symlink('./foo', './new-port', callback);

它创建了一个名为 "new-port" 且指向 "foo" 的符号链接。

fs.symlinkSync(target, path[, type])#

同步的 symlink(2)。返回 undefined

fs.truncate(path[, len], callback)#

异步的 truncate(2)。 完成回调只有一个可能的异常参数。 文件描述符也可以作为第一个参数传入,在这种情况下,fs.ftruncate() 会被调用。

fs.truncateSync(path[, len])#

同步的 truncate(2)。 返回 undefined。 文件描述符也可以作为第一个参数传入,在这种情况下,fs.ftruncateSync() 会被调用。

fs.unlink(path, callback)#

异步的 unlink(2)。 完成回调只有一个可能的异常参数。

fs.unlinkSync(path)#

同步的 unlink(2)。返回 undefined

fs.unwatchFile(filename[, listener])#

停止监视 filename 文件的变化。 如果指定了 listener,则只移除特定的监听器。 否则,所有的监听器都会被移除,且已经有效地停止监视 filename

调用 fs.unwatchFile() 且带上一个未被监视的文件名,将会是一个空操作,而不是一个错误。

注意:fs.watch()fs.watchFile()fs.unwatchFile() 更高效。 可能的话,应该使用 fs.watch() 而不是 fs.watchFile()fs.unwatchFile()

fs.utimes(path, atime, mtime, callback)#

改变 path 所指向的对象的文件系统时间戳。

atime 参数和 mtime 参数遵循以下规则:

  • 值可以是 Unix 时间戳数值、Date 对象、或数值字符串如 '123456789.0'
  • 如果值不能被转换为数值,或值是 NaNInfinity-Infinity,则会抛出错误。

fs.utimesSync(path, atime, mtime)#

fs.utimes() 的同步版本。返回 undefined

fs.watch(filename[, options][, listener])#

监视 filename 的变化,filename 可以是一个文件或一个目录。 返回的对象是一个 fs.FSWatcher

第二个参数是可选的。 如果提供的 options 是一个字符串,则它指定了 encoding。 否则 options 应该以一个对象传入。

监听器回调有两个参数 (eventType, filename)eventType 可以是 'rename''change'filename 是触发事件的文件的名称。

注意,在大多数平台,当一个文件出现或消失在一个目录里时,'rename' 会被触发。

还需要注意,监听器回调是绑定在由 fs.FSWatcher 触发的 'change' 事件上,但它跟 eventType'change' 值不是同一个东西。

说明#

fs.watch API 不是 100% 跨平台一致的,且在某些情况下不可用。

递归选项只支持 macOS 和 Windows。

可用性#

该特性依赖于底层操作系统提供的一种方法来通知文件系统的变化。

  • 在 Linux 系统中,使用 inotify
  • 在 BSD 系统中,使用 kqueue
  • 在 macOS 系统中,对文件使用 kqueue,对目录使用 FSEvents
  • 在 SunOS 系统(包括 Solaris 和 SmartOS)中,使用 event ports
  • 在 Windows 系统中,该特性依赖 ReadDirectoryChangesW
  • 在 Aix 系统中,该特性依赖 AHAFS 必须是启动的。

如果底层功能因某些原因不可用,则 fs.watch 也无法正常工作。 例如,当使用虚拟化软件如 Vagrant、Docker 等时,在网络文件系统(NFS、SMB 等)或主文件系统中监视文件或目录可能是不可靠的。

您仍然可以使用基于stat轮询的fs.watchFile(),但是这种方法更慢,可靠性也更低。

索引节点#

在 Linux 或 macOS 系统中,fs.watch() 解析路径到一个索引节点,并监视该索引节点。 如果监视的路径被删除或重建,则它会被分配一个新的索引节点。 监视器会发出一个删除事件,但会继续监视原始的索引节点。 新建的索引节点的事件不会被触发。 这是正常的行为。

AIX 文件在文件的生命周期中保留相同的 inode。在 AIX 上保存并关闭监视的文件将触发两个通知(一个用于添加新内容,一共用于拦截)。

文件名参数#

回调中提供的 filename 参数仅在 Linux、macOS、Windows、以及 AIX 系统上支持。 即使在支持的平台中,filename 也不能保证提供。 因此,不要以为 filename 参数总是在回调中提供,如果它是空的,需要有一定的后备逻辑。

fs.watch('somedir', (eventType, filename) => {
  console.log(`事件类型是: ${eventType}`);
  if (filename) {
    console.log(`提供的文件名: ${filename}`);
  } else {
    console.log('未提供文件名');
  }
});

fs.watchFile(filename[, options], listener)#

监视 filename 的变化。 回调 listener 会在每次访问文件时被调用。

options 参数可被省略。 如果提供的话,它应该是一个对象。 options 对象可能包含一个名为 persistent 的布尔值,表明当文件正在被监视时,进程是否应该继续运行。 options 对象可以指定一个 interval 属性,表示目标应该每隔多少毫秒被轮询。 默认值为 { persistent: true, interval: 5007 }

listener 有两个参数,当前的状态对象和以前的状态对象:

fs.watchFile('message.text', (curr, prev) => {
  console.log(`the current mtime is: ${curr.mtime}`);
  console.log(`the previous mtime was: ${prev.mtime}`);
});

这里的状态对象是 fs.Stat 实例。

如果你想在文件被修改而不只是访问时得到通知,则需要比较 curr.mtimeprev.mtime

注意:当一个 fs.watchFile 的运行结果是一个 ENOENT 错误时,它会调用监听器一次,且将所有字段置零(或将日期设为 Unix 纪元)。 在 Windows 中,blksizeblocks 字段会是 undefined 而不是零。 如果文件是在那之后创建的,则监听器会被再次调用,且带上最新的状态对象。 这是在 v0.10 版之后在功能上的变化。

注意:fs.watch()fs.watchFilefs.unwatchFile 更高效。 可能的话,应该使用 fs.watch 而不是 fs.watchFilefs.unwatchFile

注意:fs.watchFile() 所监听的文件消失并重新出现时,第二个回调函数中返回的 previousstat (文件重新出现)将与第一个回调函数的 previousstat (消失)相同。

这种情况会发生在:

  • 该文件被删除,然后又恢复
  • 文件重命名两次 - 第二次重命名与其原名称相同

fs.write(fd, buffer[, offset[, length[, position]]], callback)#

写入 bufferfd 指定的文件。

offset 决定 buffer 中被写入的部分,length 是一个整数,指定要写入的字节数。

position 指向从文件开始写入数据的位置的偏移量。 如果 typeof position !== 'number',则数据从当前位置写入。详见 pwrite(2)

回调有三个参数 (err, bytesWritten, buffer),其中 bytesWritten 指定从 buffer 写入了多少字节

如果以 util.promisify() 的形式调用该方法,则会返回包含 bytesWrittenbuffer 属性的 Promise 的对象。

注意,多次对同一文件使用 fs.write 且不等待回调,是不安全的。 对于这种情况,强烈推荐使用 fs.createWriteStream

在 Linux 上,当文件以追加模式打开时,指定位置的写入是不起作用的。 内核会忽略位置参数,并总是将数据追加到文件的末尾。

fs.write(fd, string[, position[, encoding]], callback)#

写入 stringfd 指定的文件。 如果 string 不是一个字符串,则该值将被强制转换为一个字符串。

position 指向从文件开始写入数据的位置的偏移量。 如果 typeof position !== 'number',则数据从当前位置写入。详见 pwrite(2)

encoding 是期望的字符串编码。

回调有三个参数 (err, written, string),其中 written 指定传入的字符串被写入多少字节。 注意,写入的字节与字符串的字符是不同的。详见 Buffer.byteLength

不同于写入 buffer,该方法整个字符串必须被写入。 不能指定子字符串。 这是因为结果数据的字节偏移量可能与字符串的偏移量不同。

注意,多次对同一文件使用 fs.write 且不等待回调,是不安全的。 对于这种情况,强烈推荐使用 fs.createWriteStream

在 Linux 上,当文件以追加模式打开时,指定位置的写入是不起作用的。 内核会忽略位置参数,并总是将数据追加到文件的末尾。

fs.writeFile(file, data[, options], callback)#

异步地写入数据到文件,如果文件已经存在,则替代文件。 data 可以是一个字符串或一个 buffer。

如果 data 是一个 buffer,则忽略 encoding 选项。它默认为 'utf8'

例子:

fs.writeFile('message.txt', 'Hello Node.js', (err) => {
  if (err) throw err;
  console.log('The file has been saved!');
});

如果 options 是一个字符串,则它指定了字符编码。例如:

fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback);

任何指定的文件描述符必须支持写入。

注意,多次对同一文件使用 fs.writeFile 且不等待回调,是不安全的。 对于这种情况,强烈推荐使用 fs.createWriteStream

注意:如果 file 指定为一个文件描述符,则它不会被自动关闭。

fs.writeFileSync(file, data[, options])#

fs.writeFile() 的同步版本。返回 undefined

fs.writeSync(fd, buffer[, offset[, length[, position]]])#

fs.writeSync(fd, string[, position[, encoding]])#

fs.write() 的同步版本。返回写入的字节数。

fs 常量#

以下常量由 fs.constants 输出。

注意:不是所有的常量在每一个操作系统上都是可用的。

文件访问常量#

以下常量用于 fs.access()

常量 描述
F_OK 该标志表明文件对于调用进程是可见的。
R_OK 该标志表明文件可被调用进程读取。
W_OK 该标志表明文件可被调用进程写入。
X_OK 该标志表明文件可被调用进程执行。

文件打开常量#

以下常量用于 fs.open()

常量 描述
O_RDONLY 该标志表明打开一个文件用于只读访问。
O_WRONLY 该标志表明打开一个文件用于只写访问。
O_RDWR 该标志表明打开一个文件用于读写访问。
O_CREAT 该标志表明如果文件不存在则创建一个文件。
O_EXCL 该标志表明如果设置了 O_CREAT 标志且文件已经存在,则打开一个文件应该失败。
O_NOCTTY 该标志表明如果路径是一个终端设备,则打开该路径不应该造成该终端变成进程的控制终端(如果进程还没有终端)。
O_TRUNC 该标志表明如果文件存在且为一个常规文件、且文件被成功打开为写入访问,则它的长度应该被截断至零。
O_APPEND 该标志表明数据会被追加到文件的末尾。
O_DIRECTORY 该标志表明如果路径不是一个目录,则打开应该失败。
O_NOATIME 该标志表明文件系统的读取访问权不再引起相关文件 atime 信息的更新。该标志只在 Linux 操作系统有效。
O_NOFOLLOW 该标志表明如果路径是一个符号链接,则打开应该失败。
O_SYNC 该标志表明文件打开用于同步 I/O。
O_DSYNC 该标志标明文件为同步I/O打开,写入操作会等待数据完整性
O_SYMLINK 该标志表明打开符号链接自身,而不是它指向的资源。
O_DIRECT 当设置它时,会尝试最小化文件 I/O 的缓存效果。
O_NONBLOCK 该标志表明当可能时以非阻塞模式打开文件。

文件类型常量#

以下常量用于 fs.Stats 对象中用于决定一个文件的类型的 mode 属性。

常量 描述
S_IFMT 用于提取文件类型码的位掩码。
S_IFREG 表示一个常规文件的文件类型常量。
S_IFDIR 表示一个目录的文件类型常量。
S_IFCHR 表示一个面向字符的设备文件的文件类型常量。
S_IFBLK 表示一个面向块的设备文件的文件类型常量。
S_IFIFO 表示一个 FIFO/pipe 的文件类型常量。
S_IFLNK 表示一个符号链接的文件类型常量。
S_IFSOCK 表示一个 socket 的文件类型常量。

文件模式常量#

以下常量用于 fs.Stats 对象中用于决定一个文件访问权限的 mode 属性。

常量 描述
S_IRWXU 该文件模式表明可被所有者读取、写入、执行。
S_IRUSR 该文件模式表明可被所有者读取。
S_IWUSR 该文件模式表明可被所有者写入。
S_IXUSR 该文件模式表明可被所有者执行。
S_IRWXG 该文件模式表明可被群组读取、写入、执行。
S_IRGRP 该文件模式表明可被群组读取。
S_IWGRP 该文件模式表明可被群组写入。
S_IXGRP 该文件模式表明可被群组执行。
S_IRWXO 该文件模式表明可被其他人读取、写入、执行。
S_IROTH 该文件模式表明可被其他人读取。
S_IWOTH 该文件模式表明可被其他人写入。
S_IXOTH 该文件模式表明可被其他人执行。