先了解一个操作系统中重要的概念 inode
(index nodes)。
inode 是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。 inode更详细介绍可参考:https://www.ruanyifeng.com/blog/2011/12/inode.html
扇区(sector)
硬盘的最小存储单位叫「扇区」(sector,每个扇区存储512bit)
操作系统一次读一个扇区效率太低,所以会一次读多个扇区
块(block)
多个扇区组成一个块,最常见的大小为4kb(即由8个扇区组成)
块是文件存取的最小单元,文件数据都存储在块中
索引节点(inode)
存储文件元信息,比如文件的创建者、文件的创建日期、文件大小等
Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。
打开文件时,系统首先找到文件的inode号码,然后通过inode号码获取inode信息。然后根据inode中的文件数据所在block读取数据。
https://mp.weixin.qq.com/s/o0eN8gBSqVMHykFXrTnikg
输出信息:
文件信息:Stats {
dev: 16777220,
mode: 33188,
nlink: 1,
uid: 501,
gid: 20,
rdev: 0,
blksize: 4096,
ino: 114457648, // inode的唯一标识码
size: 2632,
blocks: 8,
atimeMs: 1639292681311.895,
mtimeMs: 1638968536815.0586,
ctimeMs: 1638968536815.1282,
birthtimeMs: 1638968536814.7827,
atime: 2021-12-12T07:04:41.312Z,
mtime: 2021-12-08T13:02:16.815Z,
ctime: 2021-12-08T13:02:16.815Z,
birthtime: 2021-12-08T13:02:16.815Z
}
通过ls -i
列出目录中文件以及所有inode标识码:
不论是硬链接或软链接都不会将原本的源文件复制一份,只会占用非常少量的磁盘空间。
多个文件可以指向源文件同一inode。
删除其中一个文件不影响对另一个文件的访问,文件内容的修改会同步到所有文件。
只能给文件创建硬链接,不能给目录创建。
适用场景:用于镜像数据文件,防止误删。
源文件和硬链接的关系:
通过linux命令创建一个硬链接logoHard.svg
指向源文件logo.svg
。
logo.svg是已经存在的,logoHard.svg命令运行后会自动创建。
const fs = require('fs')
const fileInfo = fs.statSync('./src/logo.svg')
console.log('logo文件信息:', fileInfo)
const fileInfoHardLink = fs.statSync('./src/logoHard.svg')
console.log('logo硬链接文件信息:', fileInfoHardLink)
inode
及其对应的 block
区域。$ node link.js
logo文件信息:Stats {
dev: 16777220,
mode: 33188,
nlink: 2,
uid: 501,
gid: 20,
rdev: 0,
blksize: 4096,
ino: 114457648,
size: 2632,
blocks: 8,
atimeMs: 1639295580440.4216,
mtimeMs: 1638968536815.0586,
ctimeMs: 1639295575616.7522,
birthtimeMs: 1638968536814.7827,
atime: 2021-12-12T07:53:00.440Z,
mtime: 2021-12-08T13:02:16.815Z,
ctime: 2021-12-12T07:52:55.617Z,
birthtime: 2021-12-08T13:02:16.815Z
}
logo硬链接文件信息:Stats {
dev: 16777220,
mode: 33188,
nlink: 2,
uid: 501,
gid: 20,
rdev: 0,
blksize: 4096,
ino: 114457648,
size: 2632,
blocks: 8,
atimeMs: 1639295580440.4216,
mtimeMs: 1638968536815.0586,
ctimeMs: 1639295575616.7522,
birthtimeMs: 1638968536814.7827,
atime: 2021-12-12T07:53:00.440Z,
mtime: 2021-12-08T13:02:16.815Z,
ctime: 2021-12-12T07:52:55.617Z,
birthtime: 2021-12-08T13:02:16.815Z
}
也叫符号链接。
软链接是一个链接文件,指向源文件的地址。类似索引或者指针。
修改源文件内容,软链接内容也会改变。当删除源文件时,访问软链接会报错No such file or directory
。
源文件与软链接的关系:
20211230-162327.png
通过linux命令创建一个软链接logoSoft.svg
指向logo.svg
通过node提供的fs.symlinkSync(target, path[, type])
方法创建,其中target表示源文件,path表示软链接。
const fs = require('fs');
fs.symlinkSync('./src/logo.svg', './logoSoftV2.svg')
通过ls -il
命令可查看软链接的指向信息 & inode信息。
通过node提供的fs.lstatSync(path[, options])
方法查看。其中path表示软链接的路径。
const fs = require('fs');
const fileInfo = fs.statSync('./src/logo.svg')
console.log('logo源文件信息:', fileInfo)
const logoSoftInfo = fs.lstatSync('./src/logoSoft.svg');
console.log('logo软链接文件信息:', logoSoftInfo)
输出信息:
软链接和源文件是不同的inode,其他信息也不同
软链接文件只是存储了一个链接信息,所以文件size很小
$ node readSoftLink.js
logo源文件信息:Stats {
dev: 16777220,
mode: 33188,
nlink: 3,
uid: 501,
gid: 20,
rdev: 0,
blksize: 4096,
ino: 114457648,
size: 2632,
blocks: 8,
atimeMs: 1639299883906.419,
mtimeMs: 1639296458198,
ctimeMs: 1639296496378.1218,
birthtimeMs: 1638968536814.7827,
atime: 2021-12-12T09:04:43.906Z,
mtime: 2021-12-12T08:07:38.198Z,
ctime: 2021-12-12T08:08:16.378Z,
birthtime: 2021-12-08T13:02:16.815Z
}
logo软链接文件信息: Stats {
dev: 16777220,
mode: 41453,
nlink: 1,
uid: 501,
gid: 20,
rdev: 0,
blksize: 4096,
ino: 114734506,
size: 14,
blocks: 0,
atimeMs: 1639296562078.7632,
mtimeMs: 1639296562078.7632,
ctimeMs: 1639296562078.7632,
birthtimeMs: 1639296562078.7632,
atime: 2021-12-12T08:09:22.079Z,
mtime: 2021-12-12T08:09:22.079Z,
ctime: 2021-12-12T08:09:22.079Z,
birthtime: 2021-12-12T08:09:22.079Z
}
软链接和硬链接通过不同的方式来减少磁盘空间,那他们之间有啥区别,在具体的使用场景下我们应该怎么选择使用哪一种链接方式呢:
软链接 | 硬链接 | |
---|---|---|
inode | 软链接与源文件拥有不同的inode,是两个不同的文件 | 硬链接和源文件拥有同一个inode,它们其实互为硬链接 |
文件属性 | 链接文件 | 与源文件类型相同 |
与源文件类型相同 | 支持 | 不支持 |
链接数目 (也就是文件信息中的nlink) | nlink不会随着软链接数目增加 | 每增加一个两链接nlink也会加1 |
删除源文件 | 软链接无法正常访问 |
官方文档:http://yarnpkg.top/Clilink.html
在开发阶段的项目包,可以被其他项目所依赖。因为还在开发阶段,项目包并没有被发布,通常用
yarn link
这种方式在其他项目中来测试新功能或者debug。
场景举例:当我们在业务仓库A(如:ep_student_client)中开发需求时,仓库A依赖了我们业务自定义的sdk。这个sdk是在仓库B(如:packasges仓库中开发的@byted-ep/slardar)中开发的。
开发调试存在的问题:在开发调试时,我们如果不借助yarn link,只能通过编译发布sdk,然后在A仓库中安装sdk来验证。这样开发效率很低。
使用 yarn link:
在仓库B中运行yarn link
在仓库A中运行yarn link [package...]
通过以上命令我们可以实现仓库B中的修改可以同步到仓库A中。
yarn link源码地址:https://github.com/yarnpkg/yarn/blob/3119382885ea373d3c13d6a846de743eca8c914b/src/cli/commands/link.js
当我们运行pnpm install
进行node_modules安装的时候,会使用软链接 & 硬链接的方式来节省磁盘空间 & 提升安装效率。
通过执行pnpm install
,安装的node_modules
中文件会被分为两部分:.pnpm
目录 & 其他。
.pnpm目录:存放了所有实际安装的包
其他文件:package.json中声明的包,但是只是生成一个软链接。实际指向.pnpm中安装的包。
pnpm 有个根目录,一般都是保存在 user/.pnpm-store 下,pnpm 通过硬链接的方式保证了相同的包不会被重复下载,比如说我们已经在 repoA 中下载过一次 express@4.17.1 版本,那我们后续在 repoB 中安装 express@4.17.1 的时候是会被复用的,具体就是 repoA 中的 express 中的文件和 repoB 中的 express 中的文件指向的是同一个 inode。
纠结的链接——[1]ln[2]、ln -s、fs.symlink、require[3]
【工程化】现代前端工程化- 傻傻分不清楚的链接 fs.symlink、 [4]ln[5]、ln -s(详解与应用)[6]
linux之软连接和硬连接的区别[7]
一口气搞懂「文件系统」,就靠这 25 张图了[8]
浅谈 [9]pnpm[10] 软链接和硬链接[11]
实践:[12]pnpm[13] 解决了我的哪些痛点?[14]
以上便是本次分享的全部内容,希望对你有所帮助^_^
喜欢的话别忘了 分享、点赞、收藏 三连哦~。
欢迎关注公众号 ELab团队 收货大厂一手好文章~
我们来自字节跳动,是旗下大力教育前端部门,负责字节跳动教育全线产品前端开发工作。
我们围绕产品品质提升、开发效率、创意与前沿技术等方向沉淀与传播专业知识及案例,为业界贡献经验价值。包括但不限于性能监控、组件库、多端技术、Serverless、可视化搭建、音视频、人工智能、产品设计与营销等内容。
字节跳动校/社招内推码: BQEQ9TY
投递链接: https://jobs.toutiao.com/s/8SudHqT[15]
[1]纠结的链接——: https://kohpoll.github.io/blog/2016/05/30/hardlink-symlink-require-in-nodejs/
[2]ln、ln -s、fs.symlink、require: https://kohpoll.github.io/blog/2016/05/30/hardlink-symlink-require-in-nodejs/
[3]【工程化】现代前端工程化- 傻傻分不清楚的链接 fs.symlink、 : https://jishuin.proginn.com/p/763bfbd5a424
[4]ln、ln -s(详解与应用): https://jishuin.proginn.com/p/763bfbd5a424
[5]linux之软连接和硬连接的区别: https://segmentfault.com/a/1190000040740418
[6]一口气搞懂「文件系统」,就靠这 25 张图了: https://www.cnblogs.com/xiaolincoding/p/13499209.html
[7]浅谈 : https://zhuanlan.zhihu.com/p/442133074
[8]pnpm: https://zhuanlan.zhihu.com/p/442133074
[9] 软链接和硬链接: https://zhuanlan.zhihu.com/p/442133074
[10]实践:: https://juejin.cn/post/7036319707590295565
[11]pnpm: https://juejin.cn/post/7036319707590295565
[12] 解决了我的哪些痛点?: https://juejin.cn/post/7036319707590295565
[13]https://jobs.toutiao.com/s/8SudHqT: https://link.juejin.cn/?target=https%3A%2F%2Fjob.toutiao.com%2Fs%2FRb21Dk9
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8