44 # 流的原理

通过 fs 模块实现拷贝功能

同步的拷贝实现

新建 name.txt 文件,里面添加

凯小默的博客

在这里插入图片描述

const fs = require("fs");
const path = require("path");
// 读取默认不指定编码都是 buffer 类型
let r = fs.readFileSync(path.resolve(__dirname, "./name.txt"));
console.log(r);
// 默认会将二进制转化成字符串到文件,虽然看到的是字符串但是内部存储的是二进制
fs.writeFileSync(path.resolve(__dirname, "./new_name.txt"), r);

执行上面同步代码

在这里插入图片描述

异步的拷贝实现,不会阻塞主线程,node 是底层是 libuv,内部工作原理是多线程

const fs = require("fs");
const path = require("path");
fs.readFile(path.resolve(__dirname, "./name.txt"), function (err, data) {
    
    
    if (err) throw err;
    fs.writeFile(path.resolve(__dirname, "./new_name2.txt"), data, function (err) {
    
    
        if (err) throw err;
        console.log("写入成功");
    });
});

在这里插入图片描述

直接使用 copyFile,它的原理就是读写操作

const fs = require("fs");
const path = require("path");
fs.copyFile(path.resolve(__dirname, "./name.txt"), path.resolve(__dirname, "./new_name3.txt"), function (err) {
    
    
    if (err) throw err;
    console.log("name.txt was copied to new_name3.txt");
});

在这里插入图片描述

stream

拷贝文件会默认把整个文件读取一遍,特点不能读取比内存大的文件(会占用很多可用的内存),这个时候可以使用 stream 流,边读边写(采用分块读取写入的方式来实现拷贝),流的原理就是读一点写一点。

文件系统中内置了操作文件的方法(精确的读取文件中的部分内容)

I/O 操作:读取就是写入内存,写入就是把内存取,读取出来

读取操作:

新建 read.txt,添加 0123456789 内容

在这里插入图片描述

const fs = require("fs");
const path = require("path");
// 先读取三个到内存中
const buf = Buffer.alloc(3);
// 打开文件读取文件
// open(path, flags, callback)
// flags:r(读取),w(写入),a(追加文件)
fs.open(path.resolve(__dirname, "./read.txt"), "r", function (err, fd) {
    
    
    // fd: Number 表示的是文件描述器(file descriptor)
    // read(fd, buffer, offset, length, position, callback: (err, bytesRead, buffer)
    // buffer 的第 0 个位置开始写入,写入到 buffer 中几个,文件的读取位置是多少
    fs.read(fd, buf, 0, 3, 0, function (err, bytesRead, buffer) {
    
    
        // bytesRead: 真正的读取个数
        if (err) throw err;
        console.log("读取成功", bytesRead, buffer);
    });
});

在这里插入图片描述

写操作:

const fs = require("fs");
const path = require("path");
const wBuf = Buffer.from("凯小默");
// open(path, flags, mode, callback)
// w(写入)默认会先清空在写入,a(追加文件)
// mode:表示权限,这个可以看【拓展 Linux ls 命令】部分,默认就是 666 的权限,0o666 就是 438
fs.open(path.resolve(__dirname, "./write.txt"), "a", 438, function (err, fd) {
    
    
    if (err) throw err;
    // write(fd, buffer, offset, length, position, callback: (err, written, buffer)
    // 0 代表就是从 buffer 0 的位置开始读取,读取 6 个写入到文件的哪个位置中
    fs.write(fd, wBuf, 0, 9, 0, function (err, written, buffer) {
    
    
        if (err) throw err;
        console.log("写入成功", written, buffer);
    });
});

在这里插入图片描述

w 改成 a,再次执行

在这里插入图片描述

拓展 Linux ls 命令

Linux ls 命令

  • -a:显示所有文件及目录 (. 开头的隐藏文件也会列出)
  • -d:只列出目录(不递归列出目录内的文件)。
  • -l:以长格式显示文件和目录信息,包括权限、所有者、大小、创建时间等。
  • -r:倒序显示文件和目录。
  • -t:将按照修改时间排序,最新的文件在最前面。
  • -A:同 -a ,但不列出 "." (目前目录) 及 ".." (父目录)
  • -F:在列出的文件名称后加一符号;例如可执行档则加 "*", 目录则加 "/"
  • -R:递归显示目录中的所有文件和子目录。

在使用 ls -l 命令时,第一列的字符表示文件或目录的类型和权限。其中第一个字符表示文件类型,例如:

  • -:表示普通文件
  • d:表示目录
  • l:表示符号链接
  • c:表示字符设备文件
  • b:表示块设备文件
  • s:表示套接字文件
  • p:表示管道文件

在使用 ls -l 命令时,第一列的其余 9 个字符表示文件或目录的访问权限,分别对应三个字符一组的 rwx 权限。例如:

  • r:表示读取权限
  • w:表示写入权限
  • x:表示执行权限
  • -:表示没有对应权限

前三个字符表示所有者的权限,中间三个字符表示所属组的权限,后三个字符表示其他用户的权限。例如:

输入下面命令

ls -al

假设有下面这一行:

-rw-r--r-- 1 guok 197609   18 Jun 28 10:00 name.txt

表示文件名为 name.txt 的文件,所有者具有读写权限,所属组和其他用户只有读取权限。

最常见的更改文件权限命令:

chmod 777 name.txt

这里的 777 三位数字分别代表 user、group、other 的权限(都为7)。

  • 若要 rwx 属性则 4 + 2 + 1 = 7
  • 若要 rw- 属性则 4 + 2 = 6
  • 若要 r-x 属性则 4 + 1 = 5

猜你喜欢

转载自blog.csdn.net/kaimo313/article/details/131445020
44