读完这篇文章,你需要解答的问题
1. 什么是文件描述符?
2. 文件的编码格式有哪些?utf-8、gbk等
3. 文件读取常用的api?
4. node中路径处理常用的API
文件描述符
- Node抹平了不同系统间文件描述符的差异,统一用 数字形式的 文件描述符追踪资源
- 操作系统对打开的文件描述符数量是有限制的,因此操作完成后,要及时关闭文件描述符,否则会造成内存泄露。
- 每个系统内核里,都维护一张已经打开的文件的文件描述符的表.
fs.open()
:会打开一个新的文件描述符;只有先有了文件描述符,才能对文件进行读、写- 一般情况所有异步API都有对应的同步版本,同步API方法名的末尾多了Sync,
- 如:
Readfile
对应的同步API--readFileSync()
- 同步API记得用
try…catch…
捕捉
- 如:
文字编码处理
- 文件读取时,要注意编码格式:先将文件格式转换为UTF-8编码后,才能正常处理
- UTF-8格式
- 可能会自带BOM(BOM用来标记文本编码是Unicode编码)
- 通过文本文件的头几个字节,确定是否包含BOM,以及使用何种编码模式
- Unicode编码也有多种格式
- BOM字符不属于文件内容的一部分,只是起到标记文件编码的作用。因此文件读取时,需要去除UTF8 BOM的功能
- GBK格式
- 需要转换一下 iconv.decode
- 如何确定,读取文件时,使用哪种格式的编码方式
- 纯英文:GBK | UTF-8
- 有中文,但中文字符在 ASCII0-128范围内:GBK | UTF-8
- Node中,读取文件时,使用binary编码格式即可!
fs
fs.chown(path, uid, gid, callback)
:更改文件的所有者和群组fs.chmod(path, mode, callback)
:更改文件的权限;mode可以是string | integerfs.stat(path[, options], callback)
:检查文件是否存在(仅在不直接使用文件时,才会检查文件的可用性)- 如果只检查文件是否存在,用
fs.access(path,[mode], callback)
即可 - 不要在
open、read、readfile、write()
前,用fs.stat()
,而是直接在open
等函数内处理文件不存在的情况
- 如果只检查文件是否存在,用
说明:
同类型API:fs.stat | fs.statSync | fs.lstat | fs.lstatSync
lstat:和stat相同,只是如果path是符号链接,则查看的是链接自身,而不是它指向的文件
fs.access(path [, mode, callback(err)])
返回文件是否存在、读权限、写权限等- 不要在
open
、readFile
或writeFile
之前使用,否则会引入竞态条件;应该直接打开、或读取 - mode:fs.constants.F_OK | R_OK | W_OK
- 默认是 F_OK:文件是否存在
- 不要在
fs.accessSync(path [, mode])
- 请在
try.. catch..
中使用,避免抛出Error导致程序崩溃
- 请在
fs.existsSync(path)
- exists()已经被弃用,推荐用fs.access()或 fs.stat
- 但existsSync()不被弃用,同步函数没有callback
- 写入文件操作
fs.writeFile() | fs.appendFile()
fs.write(path)
和fs.writeFile(path)
区别- 当path是文件描述符时,writeFile()和write()是类似的
- 不同:某些异常情况下,fs.write()可能会只写入部分buffer,需要重试来写入剩余的数据
- 而fs.writeFile()会一直重试,直到完全写入,或发生错误。
fs.createWriteStream(path,options)
- 事件:open | close | ready
- 文件系统file system
- fs中的类
fs.Dir
类:fs.opendir()会返回一个该类- Dir.close() | Dir.read() | dir.path
fs.Dirent
类:用fs.readdir | fs.readdirSync时,会返回该类- isFile() | isDirectory | isSocket | dir.name
fs.FSWatcher
类:fs.watch()
会返回该类,但使用fs.watchFile时,返回的是FSStatWatcher类- 推荐用fs.watch,代替fs.watchFile和fs.unwatchFile
- 可用于监控文件的改变,如
change | close | error
fs.StatWatcher
类:fs.watchFile()会返回该类fs.Stats
类:fs.stat | statSync | lstat | fstat会返回该类- isFile | isDirectory | size ….
fs.ReadStream
类fs.WriteStream
类
- 文件权限修改:fs.chmod() | fs.chown()
- 文件内容的读写:fs.readFile() fs.writeFile | fs.readdir | fs.mkdir
- 底层文件操作:fs.open() | fs.read() | fs.write() | fs.close()
- fs.stat:检查文件是否存在,fs.stat(path, callback(err, stats):返回一个fs.stats类
- 删除文件或符号链接:fs.unlink | fs.unlinkSync
- 判断文件是否存在:如果只检查文件是否存在,用fs.access,如果有对文件的进一步操作,可以用fs.stat
- fs.access(filePath, mode, callback):测试用户对文件|目录的读、写权限,检查文件是否存在;callback中,只返回err
- fs.existsSync(path):路径是否存在
- fs.stat(file, callback):callback中,传递一个stats对象
- renameSync(oldPath, newPath)
- 如果newPath已经存在,则覆盖它
- fs.copyFile(path, dest, mode, collback):拷贝旧文件内容到新文件
- mode是可选参数,包括fs.constants.COPYFILE_EXCL | COPYFILE_FICLONE | COPYFILE+FICLONE_FORCE
- 默认是 fs.constants.COPYFILE_EXCL,如果dest存在,则拷贝操作失败
- mode是可选参数,包括fs.constants.COPYFILE_EXCL | COPYFILE_FICLONE | COPYFILE+FICLONE_FORCE
- 监控文件属性的更新—fs.watch
- 推荐用fs.watch()代替fs.watchFile和fs.unwatchFile
- 注意:fs.watch()在各个平台可能存在不一致,或在某些平台下不可用的情况
- 比如在虚拟系统或Docker中,监控文件或目录,可能是不可靠的 5.对目录的操作
- fs中的类
- 创建目录:
mkdirSync(path, options)
- 删除目录:
fs.rmdir | fs.rmdirSync
readdir | readdirSync
:返回Dirent
类,包括isFile() | isDirectory
等属性opendir
:打开目录,返回Dir
类
6.fs的promise类:新增于node 10.0.0,可用于链式调用
path
- 在node中不要使用字符串拼接的方式处理路径,使用path模块
path路径转换
-
path.join()
:多个传入的路径拼接为标准路径,然后规范化生成的路径- 如果拼接后返回的字符串长度为0,则返回当前目录
-
path.resolve()
:将路径解析为绝对路径,从右到左开始处理,后面的每个path会被追加到前面,直到构造出绝对路径- 返回的路径会被规范化,尾部的斜杠会被删除
- 如果在处理完所有给定的path后,还没生成绝对路径,就会使用当前工作目录
-
path.normalize()
:解析.././/等特殊字符,去掉多余的斜杠,将传入的路径转换为标准路径path- 标准化后的斜杠:在windows系统中是 \,但在Linux系统中是 /,所以需要统一一下,.replace(/\/g, ‘/')
读取文件路径信息
path.basename(path [, ext])
:返回path路径的最后一部分;- 如果ext存在,则返回值去掉ext
- windows情况下,ext里的内容是区分大小写的;
path.basename(‘/path1/path2/文件.html’) // 返回 文件.html
path.basename(‘/path1/path2/文件.html’, ‘.html') // 返回 文件(windows下是区分大小写的哦)
path.dirname(path)
:和base相反,返回去掉最后一个/后面的 目录前缀
path.dirname(‘/path1/path2/文件.html’) // 返回/path1/path2
path.extname()
:返回文件的扩展名,如.htmlpath.parse(path)
:返回一个对象,包括上面三个的返回值 root | dir | base | ext | name