Nodejs 中 fs 模块的使用

fsfilesystem的缩写,该模块提供本地文件的读写能力,基本上是POSIX文件操作命令的简单包装。

导入文件系统模块(fs)语法如下所示:

var fs = require("fs")

fs.stat 检测是文件还是目录

stat方法的参数是一个文件或目录,它产生一个对象,该对象包含了该文件或目录的具体信息。

fs.stat("./data/demo.js",function(err,stats){
    if(err){
        console.log(err)
        return
    }
    if(stats.isFile()){
        // 文件
    }else if(stats.isDirectory()){
        // 目录
    }
})

fs.mkdir 创建目录

mkdir 方法用于新建目录

fs.mkdir('./demo',function(err){
    if(err){
        console.log(err)
        return 
    }
    console.log("创建成功!")
})

mkdirSync 是创建目录的同步方法

fs.mkdirSync('./demo')

fs.writeFile 创建写入文件

writeFile 直接打开文件默认是 w 模式,所以如果文件存在,该方法写入的内容会覆盖旧的文件内容。

fs.writeFile('input.txt', 'hello world!', function(err){
    if(err) {
        console.log(err)
        return 
    }
    console.log("写入文件成功")
})

writeFileSync 写入文件的同步方法

fs.writeFileSync('input.txt','hello World!')

fs.readFile 读取文件

readFile 方法读取的是 Buffer,使用toString 方法转成 String类型

fs.readFile('input.txt', function(err,data){
    if(err) {
        console.log(err)
        return 
    }
    console.log(data.toString())
})

readFileSync 是读取文件的同步方法

const data = fs.readFileSync('input.txt')
console.log(data.toString())

fs.appendFile 追加文件

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

fs.appendFile('./input.txt','追加的内容',function(err,data){
    if(err){
        console.log(err)
        return 
    }
    console.log('追加成功!')
})

appendFileSync 是追加文件 的同步方法

try {
  fs.appendFileSync('./input.txt','追加的内容')
  console.log('追加成功');
} catch (err) {
  console.log(err)
}

fs.readdir 读取目录

readdir 方法用于读取目录,返回一个所包含的所有文件和子目录的数组。

fs.readdir('./data', function (err, files) {
    if (err) {
        console.log(err)
        return 
    }
    console.log(files)
})

readdirSync 是读取文件的同步方法

try {
  const files = fs.readdirSync('./data')
  console.log(files);
} catch (err) {
  console.log(err)
}

fs.rename 重命名

rename 方法用于文件的重命名或移动。

重命名文件

fs.rename('input.txt', 'new.txt', (err) => {
  if (err) throw err;
  console.log('重命名成功');
});

移动文件

fs.rename('input.txt', './data/input.txt', (err) => {
  if (err) throw err;
  console.log('移动文件完成');
});

renameSync 是 rename 同步版本

// 重命名
try {
  fs.renameSync('input.txt', 'new.txt')
  console.log("重命名成功");
} catch (err) {
  console.log(err)
}
// 移动
try {
  fs.renameSync('input.txt', './data/input.txt')
  console.log("重命名成功");
} catch (err) {
  console.log(err)
}

fs.rmdir 删除目录

rmdir 方法用于删除目录,只能删除空目录。

fs.rmdir('./demo', function (err) {
    if (err) {
        console.log(err)
        return 
    }
    console.log('删除目录成功')
})

rmdirSync 是删除目录的同步方法。

try{
    fs.rmdirSync('./demo')
    console.log("删除目录成功")
}catch(err){
    console.log(err)
}

fs.unlink 删除文件

unlink 方法用于删除文件

fs.unlink('input.txt',(err)=>{
    if(err){
        console.log(err)
        return 
    }
    console.log('删除文件成功')
})

unlinkSync 是删除文件的同步方法

try{
    fs.rmdirSync('./demo')
    console.log("删除目录成功")
}catch(err){
    console.log(err)
}

fs.createReadStream

createReadStream 方法用于从文件流读取数据,一般用于大型文本文件。
读取操作会触发data事件,发送完成会触发end事件。

const readSteam = fs.createReadStream('./input.txt')

var count = 0
var str = ""

readSteam.on('data', (data) => {
    str += data
    count++ 
})

readSteam.on('end', () => {
    console.log(str)
    console.log(count)
})

readSteam.on('error', (err) => {
    console.log(err)
})

fs.createWriteStream

createWriteStream方法创建一个写入数据流对象,该对象的write方法用于写入数据,end方法用于结束写入操作。

var str = ""
for(var i=0;i<500;i++){
    str +="写入的数据\n"
}
var writeStream = fs.createWriteStream('./input.txt');
writeStream.write(str);
writeStream.end();

writeStream.on('finish',()=>{
    console.log('写入完成')
})

pipe 管道流

管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。

var readStream = fs.createReadStream('input.txt')
var writeStream = fs.createWriteStream('out.txt')

readStream.pipe(writeStream)

练习

1.判断服务器上没有upload 文件,如果没有就创建目录。

如果有upload文件,需要先删除upload 文件才能创建upload文件夹。实现如下:

const fs = require('fs')
const path = "./upload"
function mkdir(path){
    fs.mkdir(path,(err)=>{
            if(err){
                console.log(err)
                return 
            }
            console.log('创建成功')
        })
}
fs.stat(path,(err,stats)=>{
    if(err){
        mkdir(path)
        return 
    }
    if(!stats.isDirectory()){
        fs.unlink('./upload',(error)=>{
            if(error){
                console.log(error)
                return
            }
            mkdir(path)
        })
    }
})

2.public 文件夹下有images、js、css文件夹和index.html 文件,找出public下所有的目录,放到数组中 。

const fs = require('fs')
const path = "./public"
var arr= []
fs.readdir(path, (err, files) => {
    if (err) {
        console.log(err)
        return 
    }
    (function getDir(i) {
        if (i == files.length) {
            console.log(arr)
            return 
        }
        fs.stat(path + '/' + files[i], (err,stats) => {
            if (stats.isDirectory()) {
                arr.push(files[i])
            }
            getDir(i+1)
        })
    })(0)
})

async/await 实现如下:

function isDir(file) {
    return new Promise((resolve, reject) => {
        fs.stat(file, (err, stats) => {
            if (err) {
                console.log(err)
                reject()
                return
            }
            if (stats.isDirectory()) {
                resolve(true)
            } else{
                resolve(false)
            }
        })
    })
}
function readDir() {
    return new Promise((resolve, reject) => {
        const path = "./public"
        let arr= []
        fs.readdir(path, async (err, files) => {
            if (err) {
                console.log(err)
                reject()
                return
            }
            for (var i = 0; i < files.length; i++){
                if (await isDir(path + '/' + files[i])) {
                    arr.push(files[i])
                }
            }
            resolve(arr) 
        })
    })
}
readDir().then(res => {
    console.log(res)
})
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容