文件操作

文件编码问题

1、node在读取文件的时候是不支持读取GBK编码的文件,一般都是utf8,所以有的时候我们需要读取GBK文件时,可以借助第三方插件iconv-lite来转换成我们所需要的编码形式。
/**
 * Created by 黄森 on 2017/6/7.
 */
const fs = require('fs');
const path = require('path');
const iconv = require('iconv-lite');

fs.readFile(path.join(__dirname,'./血染的风采.lrc'),(error,data)=>{
    //decode中两个参数,第一个为你要转化的buffer,第二个为你要转化的编码方式
    console.log(iconv.decode(data,'GBK'));
    // console.log(data.toString('GBK'));
});

这样就可以将我们所读取的buffer转化成GBK格式的文件,如果直接使用data.toString('GBK')的话会提示这样的错误:

buffer.js:480
          throw new TypeError('Unknown encoding: ' + encoding);
          ^

TypeError: Unknown encoding: gbk
    at Buffer.slowToString (buffer.js:480:17)
    at Buffer.toString (buffer.js:493:27)
    at fs.readFile (F:\WebstormProjects\untitled\06.js:10:22)
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:446:3)

小小案例(动态显示歌词)

lrc的歌词按照时间顺序将对应的歌词在控制台显示

/**
 * Created by 黄森 on 2017/6/7.
 */
// 动态显示歌词

//引入模块
const fs = require('fs');
const path = require('path');
const iconv = require('iconv-lite');

fs.readFile(path.join(__dirname,'./血染的风采.lrc'),(error,data)=>{
    //按照换行分割歌词
    var lines = iconv.decode(data, 'gbk').split('\n');
    // console.log(lines.length);
    //正则匹配歌词
    var regex = /\[(\d{2})\:(\d{2})\.(\d{2})\]\s(.+)/;
    //计时间差
    var begin = new Date().getTime();
    // 遍历
    lines.forEach((line) => {
        // [00:32.67] 也许我告别 将不再回来
        var matches = regex.exec(line);
        if (matches) {
            var m = parseFloat(matches[1]);
            var s = parseFloat(matches[2]);
            var f = parseFloat(matches[3]);
            var lyric = matches[4]; // 当前行歌词不是立即执行
            // 由于下达输出任务的时刻不同

            // 由于代码执行需要消耗时间,所以要减去执行时间
            var offset = new Date().getTime() - begin;
            setTimeout(() => {
                console.log(lyric);
            }, m * 60 * 1000 + s * 1000 + f - offset);
        } else {
            // 不是一行歌词
            console.log(line);
        }
    });
});

但是这种方式是一下把所有的内容全部读取到内存中,文件比较大的话就会出现卡顿,node就提供了一个读取单行文本的api

2、readline模块逐行读取文本

下面用readline模块改版读取歌词

/**
 * Created by 黄森 on 2017/6/7.
 */
// readline动态显示歌词

const fs = require('fs');
const path = require('path');
const iconv = require('iconv-lite');
const readline = require('readline');

var filename = path.join(__dirname, './../lyrics/血染的风采.lrc');

var streamReader = fs.createReadStream(filename)
  .pipe(iconv.decodeStream('gbk'));

// 利用readline读取
var rl = readline.createInterface({ input: streamReader });

var begin = new Date().getTime();
rl.on('line', (line) => {
  task(line, begin);
});

var regex = /\[(\d{2})\:(\d{2})\.(\d{2})\]\s(.+)/;

//输出歌词,抽出单独方法
function task(line, begin) {
  // [00:32.67] 也许我告别 将不再回来
  var matches = regex.exec(line);
  if (matches) {
    var m = parseFloat(matches[1]);
    var s = parseFloat(matches[2]);
    var f = parseFloat(matches[3]);
    var lyric = matches[4]; // 当前行歌词不是立即执行
    // 由于下达输出任务的时刻不同
    var offset = new Date().getTime() - begin;
    setTimeout(() => {
      console.log(lyric);
    }, m * 60 * 1000 + s * 1000 + f - offset);
  } else {
    // 不是一行歌词
    console.log(line);
  }
}
3、文件写入
异步文件写入
fs.writeFile(file,data[,option],callback(err))
同步文件写入
fs.writeFileSync(file,data,[,option])
流式文件写
fs.createWriteStream(path[,option])
默认写入操作是覆盖源文件
异步追加
fs.appendFile(file,data[,options],callback(err))
同步追加
fs.appendFileSync(file,data[,options])
  • 1)文件异步写入
/**
 * Created by 黄森 on 2017/6/7.
 */
const fs = require('fs');
const path = require('path');

//JSON.stringify({id:10})序列化
//JSON.parse  反序列化
fs.writeFile(path.join(__dirname,'./test.txt'),JSON.stringify({id:10}),(err)=>{
    if(err){
        //读文件是不存在报错
        //意外错误
        //文件权限问题
        //文件夹找不到(不会自动创建文件夹)
        console.log('error')
    }else {
        console.log('success');
    }
});

fs.writeFile()方法中系一个参数为路径,第二个参数是要写入的内容,第三个参数是回掉函数。JSON.stringify({id:10})序列化,将一个对象转化为JSON,JSON.parse 反序列化,将JSON转化为object.
同步写入fs.writeFileSync();和异步是一样的。
因为文件的写入是覆盖源文件,所以就又文件追加的这样一个需求,node提供了fs.appendFile()这样一个函数,可以在原有的基础上追加文件内容。里面的参数和fs.writeFile()是一样的。

  • 2)文件同步写入
    fs.appendFileSync(file,data[,options]),同步写入和异步是一样的,参数都相同
4、其他文件操作
重命名文件或目录/移动文件
fs.rename(oldPath,newPath,callback)
fs.renameSync(oldPath,newPath)
删除文件
fs.unlink(path,callback(err))
fs.unlinkSync(path)
验证路径是否存在(过时的API,用stat代替)
fs.exists(path,callback(exists))
fs.existsSync(path) // => 返回布尔类型 exists
获取文件信息
fs.stat(path,callback(err,stats))
fs.statSync(path) // => 返回一个fs.Stats实例
移动文件
fs.rename(oldPath,newPath)

对目录的操作

创建一个目录
fs.mkdir(path[,model],callback)
fs.mkdirSync(path[,model])
删除一个空目录
fs.rmdir(path,callback)
fs.rmdirSync(path)
读取一个目录
fs.readdir(path,callback(err,files))
fs.readdirSync(path) // => 返回files
案例:打印目录列表
/**
 * Created by 黄森 on 2017/6/7.
 */
//打印当前目录所有文件

const fs = require('fs');
const path = require('path');
require('./proto.js'); //格式化时间的js


//获取当前有没有传入目标路径

var target = path.join(__dirname,process.argv[2] || './');

fs.readdir(target,(error,files)=>{
   files.forEach(files=>{
       // console.log(path.join(target,files));
       fs.stat(path.join(target,files),(err,stats)=>{
           console.log(`${stats.mtime.format('yyyy/MM/dd HH:mm')}\t${stats.size}\t${files}`)
       })
   })
});
5、创建文件夹
/**
 * Created by 黄森 on 2017/6/8.
 */
//创建文件夹
const fs = require('fs');
const path =require('path');

fs.mkdir(path.join(__dirname,'demo'));

文件夹路径过长,无法拷贝问题

监视文件变化:
fs.watchFile(filename[, options], listener(curr,prev))
options:{persistent,interval}
fs.watch(filename[,options][,listener])

利用文件监视实现自动 markdown 文件转换
https://github.com/chjj/marked
https://github.com/Browsersync/browser-sync
大文件拷贝
https://github.com/tj/node-progress

6、文件的拷贝
// 文件的复制

const fs = require('fs');
const path = require('path');

console.time('read');//计算时间
fs.readFile('C:\\Users\\iceStone\\Desktop\\1.iso', (err, data) => {
  if (err) {
    throw err
  }
  console.timeEnd('read');
  console.time('write');
  // 读取完文件拿到
  fs.writeFile('C:\\Users\\iceStone\\Desktop\\2.iso', data, err=> {
    if (err) {
      throw err
    }
    console.timeEnd('write');
    console.log('拷贝完成');
  });
});

这种方式的话,文件太大,我们电脑的内存就会受不了,所以就会使用文件流的方式拷贝文件

// 文件流的方式的复制

const fs = require('fs');
const path = require('path');

// 创建文件的读取流,并没有读出正式的数据,开始了读取文件的任务()
var reader = fs.createReadStream('C:\\Users\\iceStone\\Desktop\\1.itcast');

// 磁盘: 7200转 6100转 转速越快 读写越快 资源消耗更大
fs.stat('C:\\Users\\iceStone\\Desktop\\1.itcast', (err, stats) => {

  if (stats) {
    
    var readTotal = 0;
    reader.on('data', (chunk) => { 
      // chunk是一个buffer(字节数组)
      console.log('读了一点 进度:' + ((readTotal += chunk.length) / stats.size * 100) + '%');
    });
    
  }

});


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容