windows下《七天学会NodeJS》学习笔记之三--文件操作
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了windows下《七天学会NodeJS》学习笔记之三--文件操作,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6230字,纯文字阅读大概需要9分钟。
内容图文
小文件拷贝
var
fs
=
require
(
‘fs‘
);
function
copy
(
src
,
dst
)
{
//接受源文件地址和目的文件地址
fs
.
writeFileSync
(
dst
,
fs
.
readFileSync
(
src
));
//从源路径中读取文件内容,然后写入目标路径
}
function
main
(
argv
)
{
copy
(
argv
[
0
],
argv
[
1
]);
}
main
(
process
.
argv
.
slice
(
2
));
//`process`是个全局变量,可通过`process.argv`获得命令行参数。由于`argv[0]`固定等于NodeJS程序文件的绝对路径,`argv[1]`固定等于主模块的绝对路径,因此第一个命令参数从`argv[2]`这个位置开始
大文件拷贝
var
fs
=
require
(
‘fs‘
);
function
copy
(
src
,
dst
)
{
fs
.
createReadStream
(
src
).
pipe
(
fs
.
createWriteStream
(
dst
));
//先创建一个源文件的只读数据流,然后创建一个文件的只写数据源,然后用`pipe`方法把两个数据流连接起来,实现边读边写的操作。
}
function
main
(
argv
)
{
copy
(
argv
[
0
],
argv
[
1
]);
}
main
(
process
.
argv
.
slice
(
2
));
Buffer(数据块)http://nodejs.org/api/buffer.html
- JS语言本身只有字符串数据类型,没有二进制数据类型。因此,NodeJS提供了一个与
String
对等的全局构造函数Buffer
来提供对二进制数据的操作。
典型用法如下:
var bin=newBuffer([0x68,0x65,0x6c,0x6f,0x6f]);//构造一个字符串
console.log(bin.length);//输出长度
bin[0];//0x68
var str = bin.toString("UTF-9");//hello,用指定编码将二进制数据转化为字符串;
var bin =newBuffer(‘hello‘,‘utf-8‘);// => <Buffer 68 65 6c 6c 6f>,将字符串转换为指定编码下的二进制数据
2.Buffer
与字符串有一个重要区别。字符串是只读的,并且对字符串的任何修改得到的都是一个新字符串,原字符串保持不变。至于Buffer
,更像是可以做指针操作的C语言数组。例如,可以用[index]
方式直接修改某个位置的字节。bin[0]
= 0x48;
,而.slice
方法也不是返回一个新的Buffer
,而更像是返回了指向原Buffer中间的某个位置的指针,因此对.slice
方法返回的Buffer的修改会作用于原Buffer
。
-
如果想要拷贝一份Buffer,得首先创建一个新的Buffer,并通过.copy方法把原Buffer中的数据复制过去。这个类似于申请一块新的内存,并把已有内存中的数据复制过去。以下是一个例子。Buffe
r将JS的数据处理能力从字符串扩展到了任意二进制数据
var
bin
=
new
Buffer
([
0x68
,
0x65
,
0x6c
,
0x6c
,
0x6f
]);
var
dup
=
new
Buffer
(
bin
.
length
);
bin
.
copy
(
dup
);
dup
[
0
]
=
0x48
;
console
.
log
(
bin
);
// => <Buffer 68 65 6c 6c 6f>
console
.
log
(
dup
);
// => <Buffer 48 65 65 6c 6f>
Stream(数据流)[http://nodejs.org/api/stream.html)
- 当内存中无法一次装下需要处理的数据时或者一边读一边处理文件时,就需要用数据流。NodeJS中通过各种
Stream
来提供对数据流的操作。Stream
基于事件机制工作,所有的Stream
的实例都继承于NodeJS提供的EventEmitter
-
还是大文件拷贝的例子,创建一个只读数据流
var
rs
=
fs
.
createReadStream
(
pathname
);
rs
.
on
(
‘data‘
,
function
(
chunk
)
{
//`data`事件会被源源不断的触发,不管`doSomething`函数是否处理得过来。
doSomething
(
chunk
);
});
rs
.
on
(
‘end‘
,
function
()
{
cleanUp
();
});
var
fs
=
require
(
‘fs‘
);
function
copy
(
src
,
dst
)
{
//接受源文件地址和目的文件地址
fs
.
writeFileSync
(
dst
,
fs
.
readFileSync
(
src
));
//从源路径中读取文件内容,然后写入目标路径
}
function
main
(
argv
)
{
copy
(
argv
[
0
],
argv
[
1
]);
}
main
(
process
.
argv
.
slice
(
2
));
//`process`是个全局变量,可通过`process.argv`获得命令行参数。由于`argv[0]`固定等于NodeJS程序文件的绝对路径,`argv[1]`固定等于主模块的绝对路径,因此第一个命令参数从`argv[2]`这个位置开始
var
fs
=
require
(
‘fs‘
);
function
copy
(
src
,
dst
)
{
fs
.
createReadStream
(
src
).
pipe
(
fs
.
createWriteStream
(
dst
));
//先创建一个源文件的只读数据流,然后创建一个文件的只写数据源,然后用`pipe`方法把两个数据流连接起来,实现边读边写的操作。
}
function
main
(
argv
)
{
copy
(
argv
[
0
],
argv
[
1
]);
}
main
(
process
.
argv
.
slice
(
2
));
String
对等的全局构造函数Buffer
来提供对二进制数据的操作。典型用法如下:
2.var bin=newBuffer([0x68,0x65,0x6c,0x6f,0x6f]);//构造一个字符串
console.log(bin.length);//输出长度
bin[0];//0x68
var str = bin.toString("UTF-9");//hello,用指定编码将二进制数据转化为字符串;
var bin =newBuffer(‘hello‘,‘utf-8‘);// => <Buffer 68 65 6c 6c 6f>,将字符串转换为指定编码下的二进制数据
Buffer
与字符串有一个重要区别。字符串是只读的,并且对字符串的任何修改得到的都是一个新字符串,原字符串保持不变。至于Buffer
,更像是可以做指针操作的C语言数组。例如,可以用[index]
方式直接修改某个位置的字节。bin[0]
= 0x48;
,而.slice
方法也不是返回一个新的Buffer
,而更像是返回了指向原Buffer中间的某个位置的指针,因此对.slice
方法返回的Buffer的修改会作用于原Buffer
。如果想要拷贝一份Buffer,得首先创建一个新的Buffer,并通过.copy方法把原Buffer中的数据复制过去。这个类似于申请一块新的内存,并把已有内存中的数据复制过去。以下是一个例子。Buffe
r将JS的数据处理能力从字符串扩展到了任意二进制数据
var bin = new Buffer ([ 0x68 , 0x65 , 0x6c , 0x6c , 0x6f ]);
var dup = new Buffer ( bin . length );
bin . copy ( dup );
dup [ 0 ] = 0x48 ;
console . log ( bin ); // => <Buffer 68 65 6c 6c 6f>
console . log ( dup ); // => <Buffer 48 65 65 6c 6f>
Stream
来提供对数据流的操作。Stream
基于事件机制工作,所有的Stream
的实例都继承于NodeJS提供的EventEmitter还是大文件拷贝的例子,创建一个只读数据流
var rs = fs . createReadStream ( pathname );
rs . on ( ‘data‘ , function ( chunk ) { //`data`事件会被源源不断的触发,不管`doSomething`函数是否处理得过来。
doSomething ( chunk );
});
rs . on ( ‘end‘ , function () {
cleanUp ();
});
继续改造代码:
var rs = fs . createReadStream ( src );
rs . on ( ‘data‘ , function ( chunk ) { //通过回调添加暂停功能,处理完毕后再继续
rs . pause ();
doSomething ( chunk , function () {
rs . resume ();
});
});
rs . on ( ‘end‘ , function () {
cleanUp ();
});
一个读写文件的例子:
var rs = fs.createReadStream(src);
var ws = fs.createWriteStream(dst);
rs . on ( ‘data‘ , function ( chunk ) { //如果写的速度太慢,出导致内存溢出
ws . write ( chunk );
});
rs . on ( ‘end‘ , function () {
ws . end ();
});
继续改造代码:
var rs = fs . createReadStream ( src );
var ws = fs . createWriteStream ( dst );
rs . on ( ‘data‘ , function ( chunk ) {
if ( ws . write ( chunk ) === false ) { //.write可以判断是写入目标了还是放了缓存了
rs . pause ();
}
});
rs . on ( ‘end‘ , function () {
ws . end ();
});
ws . on ( ‘drain‘ , function () { //判断是否已经将缓存中的数据写入标目
rs . resume ();
});
File System(文件系统)[http://nodejs.org/api/fs.html)
- NodeJS通过
fs
内置模块提供对文件的操作。主要有三类:- 文件属性读写:
fs.stat
,fs.chmod
,fs.chown
等 - 文件内容的读写:
fs.readFile
,fs.readdir
,fs.writeFile
,fs.mkdir
等 - 底层文件操作:
fs.open
,fs.read
,fs.write
,fs.close
等
- 文件属性读写:
-
fs
模块的所有异步API都有对应的同步版本,用于无法使用异步操作时,或者同步操作更方便时的情况。同步API除了方法名的末尾多了Sync
外,异常对象与执行结果的传递方式也有相应变化。下面是两个例子:
对应同步版本:fs.readFile(pathname,function(err, data){
if(err){
// Deal with error.
}else{
// Deal with data.
}
});
try{
var data = fs.readFileSync(pathname);
// Deal with data.
}catch(err){
// Deal with error.
}
Path(路径)[http://nodejs.org/api/path.html)
-
path
内置模块用来简化路径相关操作,提高代码可读性。下面是几个常用api。 -
path.normalize
将传入的路径转换为标准路径。它在linux下和windows生成的斜杠不同。var cache = {};
function store ( key , value ) {
cache [ path . normalize ( key )] = value ;
}
store ( ‘foo/bar‘ , 1 );
store ( ‘foo//baz//../bar‘ , 2 );
console . log ( cache ); // => { "foo/bar": 2 }
2.
path.join
将路径拼接为标准路径。如path.join(‘fool/‘,‘baz/‘,‘../bar‘)
;//=>"foo/bar" -
path.extname
:根据不同的扩展名作不同操作:path.extname(‘foo/bar.js‘); // => ".js"
遍历目录
- 递归算法:在需要优先考虑性能时,需要把递归算法转换为循环算法,以减少函数调用次数。
function factorial(n){
if(n ===1){
return1;
}else{
return n * factorial(n -1);
}
}
-
遍历算法:目录是一个树状结构,在遍历时一般使用深度优先+先序遍历算法。深度优先,意味着到达一个节点后,首先接着遍历子节点而不是邻居节点。先序遍历,意味着首次到达了某节点就算遍历完成,而不是最后一次返回某节点才算数。因此使用这种遍历方式时,下边这棵树的遍历顺序是A > B > D > E > C > F。
A
/ \
B C
/ \ \
D E F
-
同步遍历
function travel(dir, callback) {fs . readdirSync ( dir ). forEach ( function ( file ) {
var pathname = path . join ( dir , file );
if ( fs . statSync ( pathname ). isDirectory ()) {
travel ( pathname , callback );
} else {
callback ( pathname );
}
});
}
-
异步遍历
function travel(dir, callback, finish) {fs . readdir ( dir , function ( err , files ) {
( function next ( i ) {
if ( i < files . length ) {
var pathname = path . join ( dir , files [ i ]);
fs . stat ( pathname , function ( err , stats ) {
if ( stats . isDirectory ()) {
travel ( pathname , callback , function () {
next ( i + 1 );
});
} else {
callback ( pathname , function () {
next ( i + 1 );
});
}
});
} else {
finish && finish ();
}
}( 0 ));
});
}
-
文本编码
- 常用文本编码有
UTF8
和GBK
两种,并且:UTF8
可能还带有BOM。在读取不同编码的文本文件时,需要将文件内容转换为JS使用的UTF8编码字符串后才能正常处理。 -
移除BOM:BOM用于标记一个文本文件使用Unicode编码,其本身是一个Unicode字符("\uFEFF"),位于文本文件头部。在不同的Unicode编码下,BOM字符对应的二进制字节如下:
Bytes Encoding
----------------------------
FE FF UTF16BE
FF FE UTF16LE
EF BB BF UTF8
以下代码实现了识别和去除UTF8 BOM的功能。
function readText ( pathname ) {
var bin = fs . readFileSync ( pathname );
if ( bin [ 0 ] === 0xEF && bin [ 1 ] === 0xBB && bin [ 2 ] === 0xBF ) {
bin = bin . slice ( 3 );
}
return bin . toString ( ‘utf-8‘ );
}
-
GBK编码不在NodeJS自身支持范围内,因此,我们一般借助
iconv-lite
第三方包来转换编码。下载该NPM后,可下边方式编写一个读取GBK文本文件的函数。var iconv = require ( ‘iconv-lite‘ );
function readGBKText ( pathname ) {
var bin = fs . readFileSync ( pathname );
return iconv . decode ( bin , ‘gbk‘ );
}
- 单字节编码,如果无法预知文件编码,可以使用单字节编码来读取文件,不用关心文件是GBK还是UTF8编码。
上述例子说明直接操作单字节乱码字符时,背后对应的字节保持不变。1. GBK编码源文件内容:
var foo =‘中文‘;
2.对应字节:
76617220666F6F203D2027 D6 D0 CE C4 273B
3.使用单字节编码读取后得到的内容:
var foo =‘{乱码}{乱码}{乱码}{乱码}‘;
4.替换内容:
var bar =‘{乱码}{乱码}{乱码}{乱码}‘;
5.使用单字节编码保存后对应字节:
76617220626172203D2027 D6 D0 CE C4 273B
6.使用GBK编码读取后得到内容:
var bar =‘中文‘;
NodeJS自带了一种binary
编码可以用来实现这个方法,如下:function replace(pathname){
var str = fs.readFileSync(pathname,‘binary‘);
str = str.replace(‘foo‘,‘bar‘);
fs.writeFileSync(pathname, str,‘binary‘);
}
原文:http://blog.csdn.net/fm2005/article/details/41960363
内容总结
以上是互联网集市为您收集整理的windows下《七天学会NodeJS》学习笔记之三--文件操作全部内容,希望文章能够帮你解决windows下《七天学会NodeJS》学习笔记之三--文件操作所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。