11. 文件系统

Node使用围绕标准POSIX函数的简单包装器实现文件I/O。

可以使用以下语法导入节点文件系统(fs)模块:var fs = require("fs")

11.1. 同步与异步

fs模块中的每个方法都有同步和异步形式。 异步方法将最后一个参数作为完成函数回调,将回调函数的第一个参数作为错误。 最好使用异步方法而不是同步方法,因为前者在执行期间从不阻塞程序,而第二种方法则执行。

11.1.1. 示例

使用以下内容创建名为 input.txt 的文本文件:

IOWIKI is giving self learning content
to teach the world in simple and easy way!!!!!

让我们使用以下代码创建一个名为 main.js 的js文件:

var fs = require("fs");
// Asynchronous read
fs.readFile('input.txt', function (err, data) {
   if (err) {
      return console.error(err);
   }
   console.log("Asynchronous read: " + data.toString());
});
// Synchronous read
var data = fs.readFileSync('input.txt');
console.log("Synchronous read: " + data.toString());
console.log("Program Ended");

现在运行main.js来查看结果:$ node main.js。验证输出:

Synchronous read: IOWIKI is giving self learning content
to teach the world in simple and easy way!!!!!
Program Ended
Asynchronous read: IOWIKI is giving self learning content
to teach the world in simple and easy way!!!!!

本章的以下部分提供了一组关于主要文件I/O方法的优秀示例。

11.2. 打开文件

  • 语法:fs.open(path, flags[, mode], callback)
  • 参数:
    • path :这是包含路径的文件名的字符串。
    • flags :标志指示要打开的文件的行为。 下面提到了所有可能的值。
    • mode :设置文件模式(权限和粘滞位),但仅限于创建文件的情况。 它默认为0666,可读和可写。
    • callback :这是回调函数,它获取两个参数(err,fd)。

11.3. Flags

读/写操作的标志是:

  • r:打开文件进行阅读。 如果文件不存在,则会发生异常。
  • r+:打开文件进行读写。 如果文件不存在,则会发生异常。
  • rs:打开文件以便以同步模式读取。
  • rs+:打开文件进行读写,要求操作系统同步打开它。 请参阅 rs 的注释,谨慎使用。
  • w:打开文件进行写作。 创建文件(如果它不存在)或截断(如果存在)。
  • wx:类 w,但如果路径存在则失败。
  • w+:打开文件进行读写。 创建文件(如果它不存在)或截断(如果存在)。
  • wx+:类 w + 但是如果路径存在则失败。
  • a:打开文件进行追加。 如果文件不存在,则创建该文件。
  • ax:类 a,但如果路径存在则失败。
  • a+:打开文件进行阅读和追加。 如果文件不存在,则创建该文件。
  • ax+:类 a + 一样,但如果路径存在则失败。

11.3.1. 示例

让我们创建一个名为 main.js 的js文件,其中包含以下代码,用于打开文件input.txt进行读写。

var fs = require("fs");
// Asynchronous - Opening File
console.log("Going to open file!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File opened successfully!");   
});

现在运行main.js来查看结果:$ node main.js。验证输出:

Going to open file!
File opened successfully!

11.4. 获取文件信息

  • 语法:fs.stat(path, callback)
  • 参数:
    • path :这是包含路径的文件名的字符串。
    • callback :这是回调函数,它获取两个参数(err,stats),其中stats 是fs.Stats类型的对象,在下面的示例中打印。

除了示例中下面打印的重要属性外, fs.Stats 类中还有一些有用的方法可用于检查文件类型。 这些方法在下表中给出。

  • stats.isFile():如果是简单文件的文件类型,则返回true。
  • stats.isDirectory():如果目录的文件类型,则返回true。
  • stats.isBlockDevice():如果块设备的文件类型,则返回true。
  • stats.isCharacterDevice():如果字符设备的文件类型,则返回true。
  • stats.isSymbolicLink():如果符号链接的文件类型,则返回true。
  • stats.isFIFO():如果FIFO的文件类型,则返回true。
  • stats.isSocket():如果文件类型为asocket,则返回true。

11.4.1. 示例

让我们使用以下代码创建一个名为main.js 的js文件:

var fs = require("fs");
console.log("Going to get file info!");
fs.stat('input.txt', function (err, stats) {
   if (err) {
      return console.error(err);
   }
   console.log(stats);
   console.log("Got file info successfully!");
   // Check file type
   console.log("isFile ? " + stats.isFile());
   console.log("isDirectory ? " + stats.isDirectory());  
});

现在运行main.js来查看结果:$ node main.js。验证输出:

Going to get file info!
{ 
   dev: 1792,
   mode: 33188,
   nlink: 1,
   uid: 48,
   gid: 48,
   rdev: 0,
   blksize: 4096,
   ino: 4318127,
   size: 97,
   blocks: 8,
   atime: Sun Mar 22 2015 13:40:00 GMT-0500 (CDT),
   mtime: Sun Mar 22 2015 13:40:57 GMT-0500 (CDT),
   ctime: Sun Mar 22 2015 13:40:57 GMT-0500 (CDT) 
}
Got file info successfully!
isFile ? true
isDirectory ? false

11.5. 写一个文件

  • 语法:fs.writeFile(filename, data[, options], callback)
    • 如果文件已存在,此方法将覆盖该文件。 如果要写入现有文件,则应使用其他可用方法。
  • 参数:
    • path :这是包含路径的文件名的字符串。
    • data :这是要写入文件的String或Buffer。
    • options :第三个参数是一个保存{encoding,mode,flag}的对象。 默认情况下。 编码是utf8,模式是八进制值0666.而标志是 w
    • callback :这是一个回调函数,它获取一个参数err,在出现任何写入错误时返回错误。

11.5.1. 示例

让我们创建一个名为 main.js 的js文件,其中包含以下代码:

var fs = require("fs");
console.log("Going to write into existing file");
fs.writeFile('input.txt', 'Simply Easy Learning!', function(err) {
   if (err) {
      return console.error(err);
   }
   console.log("Data written successfully!");
   console.log("Let's read newly written data");
   fs.readFile('input.txt', function (err, data) {
      if (err) {
         return console.error(err);
      }
      console.log("Asynchronous read: " + data.toString());
   });
});

现在运行main.js来查看结果:$ node main.js。验证输出:

Going to write into existing file
Data written successfully!
Let's read newly written data
Asynchronous read: Simply Easy Learning!

11.6. 读取文件

  • 语法:fs.read(fd, buffer, offset, length, position, callback)
    • 此方法将使用文件描述符来读取文件。 如果要使用文件名直接读取文件,则应使用其他可用方法。
  • 参数:
    • fd :这是 fs.open() 返回的文件描述符。
    • buffer :这是将数据写入的缓冲区。
    • offset :这是缓冲区中开始写入的偏移量。
    • length :这是一个整数,指定要读取的字节数。
    • position :这是一个整数,指定从文件中开始读取的位置。 如果position为null,则将从当前文件位置读取数据。
    • callback :这是回调函数,它获取三个参数,(错误,bytesRead,缓冲区)。

11.6.1. 示例

让我们使用以下代码创建一个名为main.js 的js文件:

var fs = require("fs");
var buf = new Buffer(1024);
console.log("Going to open an existing file");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File opened successfully!");
   console.log("Going to read the file");
   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
      if (err){
         console.log(err);
      }
      console.log(bytes + " bytes read");
      // Print only read bytes to avoid junk.
      if(bytes > 0){
         console.log(buf.slice(0, bytes).toString());
      }
   });
});

现在运行main.js来查看结果:$ node main.js。验证输出:

Going to open an existing file
File opened successfully!
Going to read the file
97 bytes read
IOWIKI is giving self learning content
to teach the world in simple and easy way!!!!!

11.7. 关闭文件

  • 语法:fs.close(fd, callback)
  • 参数:
    • fd :这是文件fs.open()方法返回的文件描述符。
    • callback :这是回调函数除了可能的异常之外,没有给完成回调的参数。

11.7.1. 示例

让我们创建一个名为 main.js 的js文件,其中包含以下代码:

var fs = require("fs");
var buf = new Buffer(1024);
console.log("Going to open an existing file");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File opened successfully!");
   console.log("Going to read the file");
   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes) {
      if (err) {
         console.log(err);
      }
      // Print only read bytes to avoid junk.
      if(bytes > 0) {
         console.log(buf.slice(0, bytes).toString());
      }
      // Close the opened file.
      fs.close(fd, function(err) {
         if (err) {
            console.log(err);
         } 
         console.log("File closed successfully.");
      });
   });
});

现在运行main.js来查看结果:$ node main.js。验证输出:

Going to open an existing file
File opened successfully!
Going to read the file
IOWIKI is giving self learning content
to teach the world in simple and easy way!!!!!
File closed successfully.

11.8. 截断文件

  • 语法:fs.ftruncate(fd, len, callback)
  • 参数:
    • fd :这是 fs.open() 返回的文件描述符。
    • len :这是文件的长度,之后文件将被截断。
    • callback :这是回调函数除了可能的异常之外,没有给完成回调的参数。

11.8.1. 示例

让我们创建一个名为 main.js 的js文件,其中包含以下代码:

var fs = require("fs");
var buf = new Buffer(1024);
console.log("Going to open an existing file");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File opened successfully!");
   console.log("Going to truncate the file after 10 bytes");
   // Truncate the opened file.
   fs.ftruncate(fd, 10, function(err) {
      if (err) {
         console.log(err);
      } 
      console.log("File truncated successfully.");
      console.log("Going to read the same file"); 
      fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
         if (err) {
            console.log(err);
         }
         // Print only read bytes to avoid junk.
         if(bytes > 0) {
            console.log(buf.slice(0, bytes).toString());
         }
         // Close the opened file.
         fs.close(fd, function(err) {
            if (err) {
               console.log(err);
            } 
            console.log("File closed successfully.");
         });
      });
   });
});

现在运行main.js来查看结果:$ node main.js。验证输出:

Going to open an existing file
File opened successfully!
Going to truncate the file after 10 bytes
File truncated successfully.
Going to read the same file
Tutorials 
File closed successfully.

11.9. 删除文件

  • 语法:fs.unlink(path, callback)
  • 参数:
    • path – 这是包含路径的文件名。
    • callback – 这是回调函数除了可能的异常之外,没有给完成回调的参数。

11.9.1. 示例

让我们创建一个名为 main.js 的js文件,其中包含以下代码:

var fs = require("fs");
console.log("Going to delete an existing file");
fs.unlink('input.txt', function(err) {
   if (err) {
      return console.error(err);
   }
   console.log("File deleted successfully!");
});

现在运行main.js来查看结果:$ node main.js。验证输出:

Going to delete an existing file
File deleted successfully!

11.10. 创建目录

  • 语法:fs.mkdir(path[, mode], callback)
  • 参数:
    • path :这是包含路径的目录名称。
    • mode :这是要设置的目录权限。 默认为0777。
    • callback :这是回调函数除了可能的异常之外,没有给完成回调的参数。

11.10.1. 示例

让我们创建一个名为main.js 的js文件,其中包含以下代码:

var fs = require("fs");
console.log("Going to create directory /tmp/test");
fs.mkdir('/tmp/test',function(err) {
   if (err) {
      return console.error(err);
   }
   console.log("Directory created successfully!");
});

现在运行main.js来查看结果:$ node main.js。验证输出:

Going to create directory /tmp/test
Directory created successfully!

11.11. 读目录

  • 语法:fs.readdir(path, callback)
  • 参数:
    • path :这是包含路径的目录名称。
    • callback :这是回调函数,它获取两个参数(错误,文件),其中files是目录中文件名的数组,不包括 ...

11.11.1. 示例

让我们创建一个名为main.js 的js文件,其中包含以下代码:

var fs = require("fs");
console.log("Going to read directory /tmp");
fs.readdir("/tmp/",function(err, files) {
   if (err) {
      return console.error(err);
   }
   files.forEach( function (file) {
      console.log( file );
   });
});

现在运行main.js来查看结果:$ node main.js。验证输出:

Going to read directory /tmp
ccmzx99o.out
ccyCSbkF.out
employee.ser
hsperfdata_apache
test
test.txt

11.12. 删除目录

  • 语法:fs.rmdir(path, callback)
  • 参数:
    • path :这是包含路径的目录名称。
    • callback :这是回调函数除了可能的异常之外,没有给完成回调的参数。

11.12.1. 示例

让我们创建一个名为main.js 的js文件,其中包含以下代码:

var fs = require("fs");
console.log("Going to delete directory /tmp/test");
fs.rmdir("/tmp/test",function(err) {
   if (err) {
      return console.error(err);
   }
   console.log("Going to read directory /tmp");
   fs.readdir("/tmp/",function(err, files) {
      if (err) {
         return console.error(err);
      }
      files.forEach( function (file) {
         console.log( file );
      });
   });
});

现在运行main.js来查看结果:$ node main.js。验证输出:

Going to read directory /tmp
ccmzx99o.out
ccyCSbkF.out
employee.ser
hsperfdata_apache
test.txt

11.13. 方法参考

以下是Node.js中可用的文件系统模块的参考。 有关更多详细信息,请参阅官方文档。

  • fs.rename(oldPath, newPath, callback):异步重命名。除了可能的异常之外,没有给完成回调的参数。
  • fs.ftruncate(fd, len, callback):异步 ftruncate()。除了可能的异常之外,没有给完成回调的参数。
  • fs.ftruncateSync(fd, len):同步 ftruncate()
  • fs.truncate(path, len, callback):异步 truncate()。除了可能的异常之外,没有给完成回调的参数。
  • fs.truncateSync(path, len):同步截断。
  • fs.chown(path, uid, gid, callback):异步 chown()。除了可能的异常之外,没有给完成回调的参数。
  • fs.chownSync(path, uid, gid):同步 chown()
  • fs.fchown(fd, uid, gid, callback):异步 fchown()。除了可能的异常之外,没有给完成回调的参数。
  • fs.fchownSync(fd, uid, gid):同步 fchown()
  • fs.lchown(path, uid, gid, callback):异步 lchown()。除了可能的异常之外,没有给完成回调的参数。
  • fs.lchownSync(path, uid, gid):同步 lchown()
  • fs.chmod(path, mode, callback):异步 chmod()。除了可能的异常之外,没有给完成回调的参数。
  • fs.chmodSync(path, mode):同步 chmod()
  • fs.fchmod(fd, mode, callback):异步 fchmod()。除了可能的异常之外,没有给完成回调的参数。
  • fs.fchmodSync(fd, mode):同步 fchmod()
  • fs.lchmod(path, mode, callback):异步 lchmod()。除了可能的异常之外,没有给完成回调的参数。 仅适用于Mac OS X.
  • fs.lchmodSync(path, mode):同步 lchmod()
  • fs.stat(path, callback):异步 stat()。回调有两个参数(错误,统计),其中stats是fs.Stats对象。
  • fs.lstat(path, callback):异步 lstat()。回调有两个参数(错误,统计),其中stats是fs.Stats对象。lstat()stat() 相同,只是如果path是符号链接,则链接本身是stated ed,而不是它引用的文件。
  • fs.fstat(fd, callback):异步 fstat()。 回调有两个参数(错误,统计),其中stats是fs.Stats对象。 fstat()stat() 相同,除了要由statd编辑的文件由文件描述符fd指定。
  • fs.statSync(path):同步 stat()。返回fs.Stats的实例。
  • fs.lstatSync(path):同步 lstat()。返回fs.Stats的实例。
  • fs.fstatSync(fd):同步 fstat()。返回fs.Stats的实例。
  • fs.link(srcpath, dstpath, callback):异步链接。 除了可能的异常之外,没有给完成回调的参数。
  • fs.linkSync(srcpath, dstpath):同步链接。
  • fs.symlink(srcpath, dstpath[, type], callback):异步符号链接。除了可能的异常之外,没有给完成回调的参数。 type 参数可以设置为’dir’,’file’或’junction’(默认为’file’),并且仅在Windows上可用(在其他平台上被忽略)。 请注意,Windows联结点要求目标路径是绝对路径。 使用 junction 时,destination 参数将自动标准化为绝对路径。
  • fs.symlinkSync(srcpath, dstpath[, type]):同步符号链接。
  • fs.readlink(path, callback):异步 readlink()。 回调有两个参数(错误,linkString)。
  • fs.realpath(path[, cache], callback):异步 realpath()。回调有两个参数(错误,resolvePath)。可以使用process.cwd来解析相对路径。cache是映射路径的对象文字,可用于强制特定路径解析或避免对已知实际路径的其他fs.stat调用。
  • fs.realpathSync(path[, cache]):同步 realpath()。返回已解析的路径。
  • fs.unlink(path, callback):异步 unlink()。除了可能的异常之外,没有给完成回调的参数。
  • fs.unlinkSync(path):同步 unlink()
  • fs.rmdir(path, callback):异步 rmdir()。除了可能的异常之外,没有给完成回调的参数。
  • fs.rmdirSync(path):同步 rmdir()
  • fs.mkdir(path[, mode], callback):异步 mkdir()。除了可能的异常之外,没有给完成回调的参数。mode默认为0777。
  • fs.mkdirSync(path[, mode]):同步 mkdir()
  • fs.readdir(path, callback):异步 readdir()。读取目录的内容。 回调有两个参数(错误,文件),其中files是目录中文件名的数组,不包括 ...
  • fs.readdirSync(path):同步 readdir()。返回不包含 . 的文件名数组和 ..
  • fs.close(fd, callback):异步关闭。除了可能的异常之外,没有给完成回调的参数。
  • fs.closeSync(fd):同步关闭。
  • fs.open(path, flags[, mode], callback):异步文件打开。
  • fs.openSync(path, flags[, mode])fs.open() 的同步版本。
  • fs.utimes(path, atime, mtime, callback)
  • fs.utimesSync(path, atime, mtime):更改提供的路径引用的文件的文件时间戳。
  • fs.futimes(fd, atime, mtime, callback)
  • fs.futimesSync(fd, atime, mtime):更改提供的文件描述符引用的文件的文件时间戳。
  • fs.fsync(fd, callback):异步fsync。 除了可能的异常之外,没有给完成回调的参数。
  • fs.fsyncSync(fd):同步fsync。
  • fs.write(fd, buffer, offset, length[, position], callback):将缓冲区写入fd指定的文件。
  • fs.write(fd, data[, position[, encoding]], callback):将数据写入fd指定的文件。 如果数据不是Buffer实例,则该值将被强制转换为字符串。
  • fs.writeSync(fd, buffer, offset, length[, position])fs.write() 的同步版本。 返回写入的字节数。
  • fs.writeSync(fd, data[, position[, encoding]])fs.write() 的同步版本。 返回写入的字节数。
  • fs.read(fd, buffer, offset, length, position, callback):从fd指定的文件中读取数据。
  • fs.readSync(fd, buffer, offset, length, position)fs.read 的同步版本。 返回bytesRead的数量。
  • fs.readFile(filename[, options], callback):异步读取文件的全部内容。
  • fs.readFileSync(filename[, options])fs.readFile 的同步版本。返回文件名的内容。
  • fs.writeFile(filename, data[, options], callback):异步将数据写入文件,如果文件已存在则替换该文件。数据可以是字符串或缓冲区。
  • fs.writeFileSync(filename, data[, options])fs.writeFile 的同步版本。
  • fs.appendFile(filename, data[, options], callback):异步将数据附加到文件,如果文件不存在则创建该文件。 数据可以是字符串或缓冲区。
  • fs.appendFileSync(filename, data[, options])fs.appendFile 的同步版本。
  • fs.watchFile(filename[, options], listener):注意文件名的更改。每次访问文件时都会调用回调侦听器。
  • fs.unwatchFile(filename[, listener]):停止观察文件名的变化。如果指定了侦听器,则仅删除该特定侦听器。否则,将删除所有侦听器,并且您已经有效地停止了查看文件名。
  • fs.watch(filename[, options][, listener]):监视文件名的更改,其中filename是文件或目录。 返回的对象是 fs.FSWatcher
  • fs.exists(path, callback):通过检查文件系统来测试给定路径是否存在。然后使用true或false调用callback参数。
  • fs.existsSync(path)fs.exists 的同步版本。
  • fs.access(path[, mode], callback):测试用户对path指定的文件的权限。mode是一个可选的整数,指定要执行的可访问性检查。
  • fs.accessSync(path[, mode])fs.access 的同步版本。如果任何可访问性检查失败,则抛出,否则不执行任何操作。
  • fs.createReadStream(path[, options]):返回一个新的ReadStream对象。
  • fs.createWriteStream(path[, options]):返回一个新的WriteStream对象。
  • fs.symlink(srcpath, dstpath[, type], callback):异步符号链接。 除了可能的异常之外,没有给完成回调的参数。 type参数可以设置为 dirfilejunction(默认为 file),并且仅在Windows上可用(在其他平台上被忽略)。 请注意,Windows联结点要求目标路径是绝对路径。 使用 junction 时,destination参数将自动标准化为绝对路径。
下一节:Node.js全局对象本质上是全局的,并且它们在所有模块中都可用。 我们不需要在我们的应用程序中包含这些对象,而是可以直接使用它们。 这些对象是模块,函数,字符串和对象本身。