NodeJS 基于 Koa, 开发一个读取文件,并返回给客户端文件下载,以及读取文件形成列表和文件删除的代码演示

news2025/5/31 23:48:11

前言

在上一篇文章 《Nodejs 实现 Mysql 数据库的全量备份的代码演示》 中,我们演示了如何将用户的 Mysql 数据库进行备份的代码。但是,这个备份,只是备份在了服务器上了。

而我们用户的真实需求,是需要将备份文件下载到本地进行保存,于是,这里就需要一个将文件返回给客户端下载的需求。

绝对不能采用的方案

我脑袋里有一个小机灵鬼告诉我,可以这样搞,代码如下:

import * as path from 'node:path'
import * as Koa from 'koa'
import * as koaStatic from 'koa-static'

const app = new Koa()
app.use(koaStatic(path.resolve(process.cwd(), './backups')))
app.listen(3000, () => {
  console.log(`Server running on http://localhost:3000`)
})

这是绝对不可以的。因为这样就等于所有人都可以访问我们的数据库备份文件。

不过上面的代码依然有参考价值,就是配置静态文件以供访问,比如图片资源啥的。

读取备份文件,并返回一个列表

不扯淡,我们需要把数据库备份文件形成一个列表,提供给用户,然后用户根据实际需求,对所需要的备份文件进行下载。

用户鉴权和接口代码这里不展示了。这里只展示核心的读取文件,并形成列表的功能

import * as fs from 'node:fs/promises'

const listBackupData = async (ctx: Context, backDir: string) => {
  try {
    const files = await fs.readdir(backDir)
    const backupFiles = await Promise.all(
      files
        .filter((file) => file.endsWith('.sql'))
        .map(async (file) => {
          const filePath = path.join(backDir, file)
          const stats = await fs.stat(filePath)
          return {
            fileName: file,
            fileSize: stats.size,
            fileCreateTime: stats.birthtime,
          }
        }),
    )
    const list = backupFiles.sort((a, b) => new Date(b.fileCreateTime).getTime() - new Date(a.fileCreateTime).getTime())
    ctx.body = succ(list)
  } catch (error) {
    ctx.status = 500
    ctx.body = fail('获取备份列表失败', 500)
  }
}

好,通过这样一段代码,就可以实现读取数据库备份文件中的文件,并形成一个列表返回给客户端了。测试效果如下图所示

读取列表测试结果

读取文件,并提供给客户端进行下载

根据上面的列表接口,用户就可以获知数据库备份文件的文件名了。再利用文件名,我们写一个接口,提供给用户进行下载即可

用户鉴权和接口代码这里不展示了。这里只展示核心函数的代码

import * as fs from 'node:fs/promises'

const downloadBackupData = async (ctx: Context, backDir: string, fileName: string) => {
  try {
    const filePath = path.join(backDir, fileName)
    const fileExists = await fs
      .access(filePath)
      .then(() => true)
      .catch(() => false)

    if (!fileExists) {
      ctx.status = 404
      ctx.body = fail('备份文件不存在', 404)
      return
    }

    const stats = await fs.stat(filePath)
    const fileContent = await fs.readFile(filePath)

    ctx.set({
      'Content-Type': 'application/sql',
      'Content-Disposition': `attachment; filename=${encodeURIComponent(fileName)}`,
      'Content-Length': stats.size.toString(),
    })

    ctx.body = fileContent
  } catch (error) {
    ctx.status = 500
    ctx.body = fail('下载备份文件失败', 500)
  }
}

好的,我们可以看到,其实重点是 fs 库的相关使用,我们用它读取文件夹,读取文件,读取文件的信息等等。

实现下载的关键是设置返回头,通过设置返回头告诉客户端,这不是一个普通接口,而是一个文件下载。

最终效果如下:

下载效果演示

数据库备份文件删除功能的演示

OK,如果用户不停的备份数据库的话,在服务器上会形成很多备份文件,对硬盘资源形成浪费。

为避免用户硬盘占满了找我删除,于是,我决定给用户开发一个删除备份文件的接口,核心代码如下:

const deleteBackupData = async (ctx: Context, backDir: string, fileName: string) => {
  try {
    const filePath = path.join(backDir, fileName)
    const fileExists = await fs
      .access(filePath)
      .then(() => true)
      .catch(() => false)
    if (!fileExists) {
      ctx.status = 404
      ctx.body = fail('备份文件不存在', 404)
    }
    // 删除文件
    await fs.unlink(filePath)
    ctx.body = succ('删除备份文件成功')
  } catch (error) {
    ctx.status = 500
    ctx.body = fail('删除备份文件失败', 500)
  }
}

执行效果如下图所示:

删除效果演示

小结

我们日常开发中,更多的是对数据库进行 CRUD 的操作,对于文件的操作我们生疏一些。通过这个接口一系列功能的开发,让我对 NodeJS 的文件操作有了更多的认知。

如果本文对您有所增益,辛苦看官您用发财的小手点个赞吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2392272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么在我的Flask里面有两个路由,但是在网页里有一个却不能正确访问到智能体

1. /zhoushibo 能访问,/chat 直接浏览器访问报 Method Not Allowed 原因: /zhoushibo 路由是你用 app.route(/zhoushibo) 定义的,返回的是一个HTML网页,浏览器访问没问题。 /chat 路由你用的是 app.route(/chat, methods[POST])…

哈工大计算机系统2024大作业——Hello的程序人生

计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 人工智能 学   号 2022112040 班 级 2203601 学 生 郄东昕 指 导 教 师 吴锐 计算机科学与技术学院…

2025年软件测试面试八股文(含答案+文档)

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 Part1 1、你的测试职业发展是什么? 测试经验越多,测试能力越高。所以我的职业发展是需要时间积累的,一步步向着高级测试工程师…

Flutter3.22适配运行鸿蒙系统问题记录

Flutter3.22适配运行鸿蒙系统问题记录 一:适配条件适配过程问题记录(1)环境配置问题(2)Concurrent modification during iteration: Instance(length:2) of_GrowableList 报错(3)三方插件寻找替…

秋招Day10 - JVM - 内存管理

JVM组织架构主要有三个部分:类加载器、运行时数据区和字节码执行引擎 类加载器:负责从文件系统、网络或其他来源加载class文件,将class文件中的二进制数据加载到内存中运行时数据区:运行时的数据存放的区域,分为方法区…

Spring Boot 3.5.0中文文档上线

Spring Boot 3.5.0 中文文档翻译完成,需要的可收藏 传送门:Spring Boot 3.5.0 中文文档

Redisson学习专栏(一):快速入门及核心API实践

文章目录 前言一、Redisson简介1.1 什么是Redisson?1.2 解决了什么问题? 二、快速入门2.1 环境准备 2.2 基础配置三、核心API解析3.1 分布式锁(RLock)3.2 分布式集合3.2.1 RMap(分布式Map)3.2.2 RList&…

Pandas学习入门一

1.什么是Pandas? Pandas是一个强大的分析结构化数据的工具集,基于NumPy构建,提供了高级数据结构和数据操作工具,它是使Python成为强大而高效的数据分析环境的重要因素之一。 一个强大的分析和操作大型结构化数据集所需的工具集基础是NumPy…

基于Piecewise Jerk Speed Optimizer的速度规划算法(附ROS C++/Python仿真)

目录 1 时空解耦运动规划2 PJSO速度规划原理2.1 优化变量2.2 代价函数2.3 约束条件2.4 二次规划形式 3 算法仿真3.1 ROS C仿真3.2 Python仿真 1 时空解耦运动规划 在自主移动系统的运动规划体系中,时空解耦的递进式架构因其高效性与工程可实现性被广泛采用。这一架…

游戏引擎学习第312天:跨实体手动排序

运行游戏并评估当前状况 目前排序功能基本已经正常,能够实现特定的排序要求,针对单一区域、单个房间的场景,效果基本符合预期。 不过还有一些细节需要调试。现在有些对象的缩放比例不对,导致它们看起来有些怪异,需要…

智警杯备赛--数据库管理与优化及数据库对象创建与管理

sql操作 插入数据 如果要操作数据表中的数据,首先应该确保表中存在数据。没有插入数据之前的表只是一张空表,需要使用insert语句向表中插入数据。插入数据有4种不同的方式:为所有字段插入数据、为指定字段插入数据、同时插入多条数据以及插…

MySQL 在 CentOS 7 环境下的安装教程

🌟 各位看官好,我是maomi_9526! 🌍 种一棵树最好是十年前,其次是现在! 🚀 今天来学习Mysql的相关知识。 👍 如果觉得这篇文章有帮助,欢迎您一键三连,分享给更…

K8S集群主机网络端口不通问题排查

一、环境: k8s: v1.23.6 docker: 20.10.14 问题和故障现象:devops主机集群主机节点到端口8082不通(网络策略已经申请,并且网络策略已经实施完毕),而且网络实施人员再次确认,网络策…

python打卡day39

知识点回顾 图像数据的格式:灰度和彩色数据模型的定义显存占用的4种地方 模型参数梯度参数优化器参数数据批量所占显存神经元输出中间状态 batchisize和训练的关系 课程代码: # 先继续之前的代码 import torch import torch.nn as nn import torch.opti…

3.8.5 利用RDD统计网站每月访问量

本项目旨在利用Spark RDD统计网站每月访问量。首先,创建名为“SparkRDDWebsiteTraffic”的Maven项目,并添加Spark和Scala的依赖。接着,编写Scala代码,通过SparkContext读取存储在HDFS上的原始数据文件,使用map和reduce…

尚硅谷redis7 49-51 redis管道之理论简介

前提redis事务和redis管道有点像,但本质上截然不同 49 redis管道之理论简介 面试题 如何优化频繁命令往返造成的性能瓶颈? redis每秒可以承受8万的写操作和接近10万次以上的读操作。每条命令都发送、处理、返回,能不能批处理一次性搞定呢…

openEuler安装MySql8(tar包模式)

操作系统版本: openEuler release 22.03 (LTS-SP4) MySql版本: 下载地址: https://dev.mysql.com/downloads/mysql/ 准备安装: 关闭防火墙: 停止防火墙 #systemctl stop firewalld.service 关闭防火墙 #systemc…

基于python,html,flask,echart,ids/ips,VMware,mysql,在线sdn防御ddos系统

详细视频:【基于python,html,flask,echart,ids/ips,VMware,mysql,在线sdn防御ddos系统-哔哩哔哩】 https://b23.tv/azUqQXe

Git:现代软件开发的基石——原理、实践与行业智慧·优雅草卓伊凡

Git:现代软件开发的基石——原理、实践与行业智慧优雅草卓伊凡 一、Git的本质与核心原理 1. 技术定义 Git是一个分布式版本控制系统(DVCS),由Linus Torvalds在2005年为管理Linux内核开发而创建。其核心是通过快照(Sna…

NLua性能对比:C#注册函数 vs 纯Lua实现

引言 在NLua开发中,我们常面临一个重要选择:将C#函数注册到Lua环境调用,还是直接在Lua中实现逻辑? 直觉告诉我们,C#作为编译型语言性能更高,但跨语言调用的开销是否会影响整体性能?本文通过基准…