Node.js(二)

由Node.js(一)可以得知,通过fs中的readFile和writeFile可以复制一个文件,但若是进行大文件的拷贝,使用readFile和writeFile会出现内存溢出问题,那又该如何解决呢?为了能够进行大文件的复制,fs核心模块中便又提供了另外两种方法:createReadStream和createWriteStream,此两种方式为文件读写流。
以下,使用一个来说明如何使用文件读写流来进行大文件的拷贝复制:

//导入核心模块
const fs=require("fs");
const path=require("path");

let sourcePath=process.argv[2];//源文件路径,为node命令行中的第三个参数,即索引为2的参数
let targetPath=process.argv[3];//目标路径,为node命令行中的第四个参数,即索引为3的参数

let reader=fs.createReadStream(sourcePath);//创建读文件流,读取源文件路径
let writter=fs.createWriteStream(targetPath);//创建写文件流,写入的目标路径

const totalSize=fs.statSync(sourcePath).size;//计算源文件的大小
const currSize=0;//当前已复制的大小
const percent=0;//当前已复制的大小占总大小的百分比

reader.on("data",function(chunk){
    currSize+=chunk.length;//更新当前已复制的大小,在原有基础上加上已复制的大小
    percent=currSize/totalSize*100+"%";//计算百分比
    writter.write(chunk);//将复制的文件写入
    console.log("当前完成:"+percent);//显示复制进度
})

reader.on("end",function(){
    writter.end(function(){
        console.log("success");//复制结束后提示成功信息
    })
})

进行大文件的复制,除了通过文件读写流来实现以外,还可以通过pipe管道来实现,虽然管道相对于文件读写流而言减少了许多代码量,但管道无法实时计算显示复制的进度百分比进度信息。
除了文件的复制,今天向大家介绍node.js中的另一个核心模块:net。
net可以开启一个Socket服务器体验,通过net,可以自行开启一个服务器,可以自行制作一款简约的类似腾讯QQ的聊天小软件,且以下代码块便是聊天软件进行通讯的基本原理。
例:

//client.js
const net =require("net");//导入核心模块
var socket=net.createConnection(8080,"本机IP地址");//创建连接,连接地址为本机IP地址的8080端口
socket.on("data",function(data){
    console.log(data.toString());//将获取的信息buffer类型进行处理
})

process.stdin.setEncoding("utf8");
process.stdin.on("data",function(data){
    socket.write(data);
})
//server.js
const net=require("net");//导入核心模块
var clients={};//定义存储对象
var time=new Date();//获取当前时间
var year=time.getFullYear();//当前年
var month=time.getMonth()+1;//当前月
var day=time.getDate();//当前日
var h=time.getHours();//当前时
var m=time.getMinutes();//当前分
var s=time.getSeconds();//当前秒
h=h<10?"0"+h:h;//若时小于10,则在前补0
m=m<10?"0"+m:m;//若分小于10,则在前补0
s=s<10?"0"+s:s;//若秒小于10,则在前补0
const server=net.createServer(function(clientSocket){
    clientSocket.write(` //提示用户指令输入格式,在此为ES6写法
        聊天服务支持的指令有:
        1、账号注册:{"cmd":"addUser","content":"用户名"}
        2、私聊:{"cmd":"privateMessage","toUser":"用户名","content":"聊天消息"}
        3、群发:{"cmd":"all","content":"聊天消息"}
    `);
    clientSocket.on("error",function(){
        console.log("有人离开了聊天室");
    })

    clientSocket.on("data",function(data){
        try{//捕获异常
            JSON.parse(data.toString().trim());
        }catch(e){
            clientSocket.write("格式错误,请重新输入!");
            return;
        }

        var json=JSON.parse(data.toString().trim());
        console.log(data.toString().trim());
        switch(json.cmd){//判断用户输入指令,对于不同指令执行不同代码
            case "addUser":
                for(var key in clients){
                    if(json.content==key){
                        clientSocket.write("该用户名已存在,请重新输入!");
                        return;
                    }
                }

                clients[json.content]=clientSocket;
                clientSocket.write(`恭喜${json.content}注册成功!`);
                break;
            case "privateMessage":
                for(var key in clients){
                    if(json.toUser==key){
                        clients[json.toUser].write(year+"-"+month+"-"+day+" "
                        +h+":"+m+":"+s+"\n"+json.content);
                        return;
                    }
                }
                clientSocket.write("该用户不存在或已离线");

            case "all":
                for(var key in clients){
                    clients[key].write(year+"-"+month+"-"+day+" "
                        +h+":"+m+":"+s+"\n"+json.content);
                }
                break;
            default:
                console.log("I don't you want to what");
                break;
        }
    })
})
server.listen("8080","本机IP地址",function(){
    console.log("服务器已开启,可以进行连接");
})

注:使用命令窗口运行时,需先运行node server.js,启动服务器才可运行node client.js。可以打开多个命令窗口运行client.js文件,通过此方式可测试通信效果。只是,以上代码块只显示了通信的时间,未能实现显示谁发送后信息给了谁,且还有许多可以改进的地方。

你可能感兴趣的:(学习心得及收获)