软件系统和文件读写

一.完整的软件系统


我们平时经常会使用一些APP或者网页,但是其实这些只是一个软件系统的一部分,在软件系统中服务端至关重要,无论我们使用的是Android还是IOS其实数据都不是存储在我们手机上的,而是存储在服务器的数据库中的,由服务端语言去操作查询返回给客户端,常见的服务端语言或者运行时环境有:Java Golang Node.js等等,如下就是一个完整的软件系统。

二.为什么推荐Node


对于前端技术人员而言对于服务端的学习首先推荐学习Node开发服务器,Node优点有很多。

  1. 一方面Node在服务器端的性能是比较高的。
  2. 对于一个前端开发而言去学习Java需要学习的内容是比较多的。
  3. 如果在后续想要学习SSR相关的知识,其实是离不开Node的。
  4. 使用相同的语言,前后端一体化,使用TypeScript甚至可以共享类型。

三.什么是Node.js


😃Node.js是一个基于V8引擎的JavaScript运行环境,也就是说Node是基于V8引擎来运行执行JavaScript代码的,但是不仅仅有V8引擎,Node中和Chorme在架构方面也有很大的差异,因为在浏览器中需要解析和渲染HTML,CSS等内容,另外还要支持浏览器操作的API,并且实现自己的事件循环。

🥹在Node中我们相对于浏览器中需要其他另外的操作,比如文件的读写,网络IO,加密,压缩解压文件。

四.Node.js架构


Node关键组件叫做LIBUV是一个由C语言编写的库,libuv提供了事件循环、文件系统读写、网络IO、线程池等等内容,以下是Node的JavaScript执行过程。

  1. Application模块就是我们编写的JavaScript代码,在Node中交由V8引擎执行。
  2. V8 Engine经过V8引擎的执行的JavaScript代码,然后通过Node.js Bindings与LIBUV进行交互。
  3. Event Queue经过Node.js Bindings系统操作后进入事件队列,然后进行事件循环。
  4. 任务经过事件循环然后对应的执行相应的工作线程worker Threads向操作系统内核执行调用。
  5. 当相应的任务执行完毕后会返回结果,返回的结果会通过回调函数一级一级的返回,就可以拿到数据了。

五.内置模块fs之文件读取


😃fs全称是文件系统,在服务端中的大多数操作就是从数据库中读取数据然后对数据进行处理,处理完之后返回给前端,其实Node之所以能够做服务端应用程序很大的一点就是因为有文件系统,同时所有的后端编程语言都有自己的文件系统,文件系统大致上做的是如下这样的一个操作过程。

借助于Node帮我们封装的文件系统,我们可以在任何操作系统上面直接去操作文件,这也是它可以成为前端自动化脚本等热门工具的原因。

fs模块的API非常多,我们不可能也没有必要全部学习,在学习阶段我们只需要学习常用的即可,其他内容在开发中遇到的时候再去查询即可,Node文件系统的API大致分为三种:

  1. 同步操作文件,代码会被阻塞,不会继续执行。
  2. 异步回调函数操作文件,代码不会被阻塞,需要传入回调函数,当获取到结果时,回调函数执行。
  3. 异步Promise操作文件,代码不会被阻塞,通过fs.promises调用方法操作,会返回一个Promise,可以通过then和catch进行操作。

😃同步读取文件:

js 复制代码
const fs = require("fs")
let text = fs.readFileSync("./test.txt", {
  encoding: 
})
console.log(text)

🥹异步回调函数的读取方式:

js 复制代码
const fs = require("fs")
fs.readFile("./test.txt", "utf-8", (err, res) => {
  if (err) {
    console.log("文件读取错误", err)
  } else {
    console.log(res)
  }
})

👽异步Promise的读取方式:

js 复制代码
const fs = require("fs")
fs.promises.readFile("./test.txt", {
  encoding: 'utf-8'
}).then((res) => {
  console.log(res)
}).catch((err) => {
  console.log("文件读取报错", err)
})

六.文件描述符


在常见的操作系统上,对于每个进程,内核都维护着一张当前打开的文件和资源表格,每个打开的文件都会分配一个称之为文件描述符的简单的数字表示符,在系统层,所有的文件系统都使用这些文件描述符来标识和跟踪每个特定的文件,Window系统使用了一个虽然不同但是概念上类似的机制来跟踪资源。

js 复制代码
const fs = require("fs")
fs.open("./test.txt", (err, fd) => {
  if (err) {
    console.log("文件打开失败")
  } else {
    console.log(fd)
  }
})

通过上述的内容就可以获取到文件描述符,然后通过文件描述符我们就可以直接进行对应文件的操作,比如我可以使用文件描述符来进行文件的写入操作。

js 复制代码
const fs = require("fs")
fs.open("./test.txt", (err, fd) => {
  if (err) {
    console.log("文件打开失败")
  } else {
    const content = "Hello World!!!"
    fs.writeFile("./test.txt", content, (err, data) => {
      if (err) {
        console.log(err)
      } else {
        console.log("文件写入成功")
      }
    })
  }
})

我们也可以通过文件描述符来获取当前文件的信息。

js 复制代码
const fs = require("fs")
fs.open("./test.txt", (err, fd) => {
  if (err) {
    console.log("文件打开失败")
  } else {
    const content = "Hello World!!!"
    fs.fstat(fd, (err, data) => {
      if (err) {
        console.log("获取文件信息失败")
      } else {
        console.log(data)
      }
    })
  }
})

然后我们就可以打印出下面的这些内容,也就是当前文件的基本信息。

六.内置模块fs之文件写入


我们模拟一个场景,客户端传递过来一段数据,这个时候我们需要将这些内容写入到服务器的某个文件,这个时候我们应该怎么做哪?其实无论再什么语言中我们的做法基本上都是一样的,就是使用对应语言的文件系统来将获取的内容进行写入。

js 复制代码
const fs = require("fs")
const content = "这是一首简单的歌~"
fs.writeFile("./test.js", content, { flag: 'a+' }, (err,data)=> {
  if (err) {
    console.log("文件写入错误")
  }else{
    console.log("文件写入成功")
  }
})

如上代码就是Node文件系统的写入方式,和读取方式一样Node的写入方式也分为三类,分别是同步读取,异步回调读取和异步Promise方式的读取,上面我们使用的是异步回调函数的写入方式,我们分别来演示下其余的两种

js 复制代码
// 同步读取
const fs = require("fs")
const content = "这是一首悲伤的歌~"
let data = fs.writeFileSync("./test.txt", content, {
  flag: "w",
  encoding: "utf-8"
})
console.log(data)

另外一种就是Promise的读取方式。

js 复制代码
const fs = require("fs")
const content = "这是一首欢乐的歌~"
fs.promises.writeFile("./test.txt", content, {
  flag: 'a+',
  encoding: 'utf-8'
}).then((res) => {
  console.log(res)
}).catch((err) => {
  console.log("文件写入错误", err)
})

😃在上述的文件写入中你可能会发现有个特别的option这个选项中分别是encodingflag这两个参数分别指代的意思是编码方式,我们一般指定的都是utf-8编码和对文件操作方式的限制,flag的值有很多但是我们平时使用的有以下几种。

  1. w:打开文件写入,默认值。
  2. w+:打开文件进行读写,可读可写,如果文件不存在则创建文件。
  3. r:打开文件进行读取,读取时候的默认值。
  4. r+:打开文件进行读写,如果文件不存在则抛出默认值。
  5. a:打开要写入的文件,把流放在文件的末尾,如果不存在则创建文件。
  6. a+:打开文件进行读写,可读可写,将流放在文件末尾,不存在则创建文件。

七.总结


😁我们这篇文章主要介绍了一个完整的软件系统是什么样的,以及它包含的几个部分,比如客户端,服务端等等,其中服务端是一个软件系统中重要的组成部分,然后我们介绍了Node的基本的组成部分,之后进行Node文件系统的读写的介绍,这也是为什么Node能够做服务端的原因。

相关推荐
正小安1 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
_.Switch3 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光3 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   3 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   3 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web3 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常3 小时前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
莹雨潇潇4 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
Jiaberrr4 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
Tiffany_Ho5 小时前
【TypeScript】知识点梳理(三)
前端·typescript