软件系统和文件读写

一.完整的软件系统


我们平时经常会使用一些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能够做服务端的原因。

相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax