io基础入门

压缩的封装

参考:https://blog.csdn.net/qq_29897369/article/details/120407125?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-120407125-blog-120163063.235v38pc_relevant_sort_base3&spm=1001.2101.3001.4242.1&utm_relevant_index=3

Resource

Java的标准java.net.URL类和各种URL前缀的标准处理程序还不足以满足对所有低级资源的访问;Resource接口在Spring和Spring中被大量使用
用实用程序类:资源抽象不能取代功能。它尽可能地包装它。例如,UrlResource包装一个URL,并使用包装的URL来完成它的工作

Spring包括几个内置的资源实现:

UrlResource

UrlResource包装了一个java.net.URL,可用于访问通常可以通过URL访问的任何对象,如文件、HTTPS目标、FTP目标等
路径字符串包含一个众所周知的(对属性编辑器来说)前缀(例如classpath:),它将为该前缀创建一个适当的专门化资源;
如果它不识别前缀,则假定该字符串是标准URL字符串并创建UrlResource;

ClassPathResource

该类表示应该从类路径获得的资源
JavaBeans PropertyEditor识别字符串路径上的特殊前缀classpath:,并在这种情况下创建ClassPathResource;

/**
getPath: 返回此资源的路径:a.txt
getAbsolutePath: /Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/target/test-classes/a.txt
**/
@Test
public void demo3(){ClassPathResource classPathResource = new ClassPathResource("a.txt");System.out.println(classPathResource.getPath());try {System.out.println(classPathResource.getFile().getAbsolutePath());} catch (IOException e) {throw new RuntimeException(e);}
}

test-classes和classes的区别:一个是@test资源resources和一个是项目资源resources
注意: 如果test-classes和classes资源不存在需要,maven重新install

FileSystemResource

这是java.io.File句柄的Resource实现
支持文件解析和URL解析;

PathResource

是一个纯粹的基于java.nio.path.Path的FileSystemResource替代品

ServletContextResource

这是ServletContext资源的Resource实现,用于解释相关web应用程序根目录中的相对路径。

InputStreamResource

InputStreamResource是给定InputStream的资源实现

ByteArrayResource

这是给定字节数组的Resource实现。它为给定的字节数组创建一个ByteArrayInputStream。

ResourceLoader

所有应用程序上下文实现ResourceLoader接口。因此,所有应用程序上下文都可以用于获取Resource实例。
会为每个上下文返回适当的对象。(ServletContextResource,FileSystemResource)
可以通过指定任何标准java.net.URL前缀来强制使用UrlResource。使用文件和https前缀的示例如下:

Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
Resource template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");

classpath:
classpath:com/myapp/config.xml
file:
file:///data/config.xml
https:
https://myserver/logo.png
/data/config.xml:
取决于底层的ApplicationContext。

ResourcePatternResolver

Ant-style路径模式解析为资源对象

PathMatchingResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();Resource[] resources = resourcePatternResolver.getResources(mapperLocations);sqlSessionFactoryBean.setMapperLocations(resources);
@Test
public void demo4() {PathMatchingResourcePatternResolver resource = new PathMatchingResourcePatternResolver();Resource resource1 = resource.getResource("classpath:a.txt");try {System.out.println(resource1.getFile().getAbsolutePath());} catch (IOException e) {throw new RuntimeException(e);}try {Resource[] resources = resource.getResources("*.txt");for (Resource resource2 : resources) {System.out.println(resource2.getFile().getAbsolutePath());
//                        /Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/target/test-classes/a.txt
//                        /Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/target/test-classes/b.txt
//                        /Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/target/test-classes/c.txt}} catch (IOException e) {throw new RuntimeException(e);}
}

classpath*:

classpath*:/config/beans.xml

您还可以依赖于ResourceLoader的自动装配,作为实现ResourceLoaderAware接口的替代方案。

资源路径没有前缀,根据应用程序上下文的确切类型;
如果需要强制使用特定的资源类型,可以使用前缀

@Component
public class MyBean {private final Resource template;public MyBean(@Value("${template.path}") Resource template) {this.template = template;}// ...
}

Ant-style Patterns

/WEB-INF/-context.xml
com/mycompany/**/applicationContext.xml
file:C:/some/path/
-context.xml
classpath:com/mycompany/**/applicationContext.xml

通配符类路径依赖于底层ClassLoader的getResources()方法

相对路径相对于当前工作目录,而绝对路径相对于文件系统的根目录

hutool加载资源

import cn.hutool.setting.dialect.Props;Props props = new Props("demo.properties");
System.out.println(props.get("name"));

类加载器加载资源

// 路径 /Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/src/main/java
package com.wx.utils.Demo
public class Demo {public static void main(String[] args) {System.out.println(Demo.class.getClassLoader().getResource("").getPath());// /Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/target/classes/System.out.println(Demo.class.getClassLoader().getResource("application.yml").getPath());// /Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/target/classes/application.ymlSystem.out.println(Demo.class.getClassLoader().getResource("com/wx/WxApplication.class").getPath());// /Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/target/classes/com/wx/WxApplication.classSystem.out.println(Demo.class.getResource("").getPath());// /Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/target/classes/com/wx/utils/System.out.println(Demo.class.getResource("Demo.class").getPath());// /Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/target/classes/com/wx/utils/Demo.classInputStream is = Demo.class.getClassLoader().getResourceAsStream("demo.properties");Properties properties = new Properties();try {properties.load(is);System.out.println(properties.get("name"));} catch (IOException e) {throw new RuntimeException(e);}}
}

demo.properties

name=zjy

在这里插入图片描述

File类

参考: https://www.ydlclass.com/doc21xnv/java/first/javase/12%E3%80%81IO%E6%B5%81/#_6%E3%80%81file%E7%B1%BB%E7%9A%84%E8%8E%B7%E5%8F%96%E5%8A%9F%E8%83%BD%E5%92%8C%E4%BF%AE%E6%94%B9%E5%90%8D%E5%AD%97%E5%8A%9F%E8%83%BD
​ 在 Java 中,File 类是 java.io 包中唯一代表磁盘文件本身的对象。File 类定义了一些与平台无关的方法来操作文件,File类主要用来获取或处理与磁盘文件相关的信息,像文件名、 文件路径、访问权限和修改日期等,还可以浏览子目录层次结构。   File 类表示处理文件和文件系统的相关信息。也就是说,File 类不具有从文件读取信息和向文件写入信息的功能,它仅描述文件本身的属性。
File(String pathname)
File(File parent,String child)
File file = new File(“D:\code\a.txt”);
File file = new File(“D:\code”);
File child = new File(file,“a.txt”);

File类创建和删除功能

boolean createNewFile() 指定路径不存在该文件时创建文件,返回true 否则false
boolean mkdir() 当指定的单击文件夹不存在时创建文件夹并返回true 否则false
boolean mkdirs() 当指定的多级文件夹在某一级文件夹不存在时,创建多级文件夹并返回true 否则false
boolean delete() 删除文件或者删除单级文件夹

File类的判断功能

boolean exists() 判断指定路径的文件或文件夹是否为空
boolean isAbsolute() 判断当前路径是否是绝对路径
boolean isDirectory() 判断当前的目录是否存在
boolean isFile() 判断当前的目录是否是一个文件
boolean isHidden() 判断当前路径是否是一隐藏文件

File类的获取功能和修改名字功能

File getAbsoluteFile() 获取文件的绝对路径,返回File对象
String getAbsolutePath() 获取文件的绝对路径,返回路径的字符串
String getParent() 获取当前路径的父级路径,以字符串形式返回该父级路径
String getName() 获取文件或文件夹的名称
String getPath() 获取File对象中封装的路径
long lastModified() 以毫秒值返回最后修改时间
long length() 返回文件的字节数
boolean renameTo(File dest) 将当前File对象所指向的路径修改为指定File所指向的路径

文件夹列表操作

返回值 方法 描述
String list() 得到这个文件夹下的所有文件,返回路径数组
String[] list(FilenameFilter filter) 通过过滤器过滤文件,过滤通过文件名过滤,返回路径数组
File[] listFiles() 得到这个文件夹下的所有文件,返回文件数组
File[] listFiles(FileFilter filter) 通过过滤器过滤文件,过滤通过文件过滤,返回文件数组
File[] listFiles(FilenameFilter filter) 通过过滤器过滤文件,过滤通过文件名过滤,返回文件数组

public class FileTest {@Testpublic void demo(){getImageName(new File("/Users/yyyyjinying/Downloads"));}private void getImageName(File file) {if (file.isDirectory()) {File[] files = file.listFiles(new FilenameFilter() {@Overridepublic boolean accept(File dir, String name) {if (dir.isDirectory() || dir.getName().endsWith(".png")) {return true;}return false;}});for (File file1 : files) {getImageName(file1);}} else if(file.getName().endsWith(".png")) {System.out.println(file.getName());}}
}

IO流

输入流和输出流:是否写入程序内存;
字节流和字符流:是一个字节一个字节的读取或写入

分类字节输入流字节输出流字符输入流字符输出流
抽象基类InputStreamOutputStreamReaderWriter
访问文件FileInputStreamFileOutputStreamFileReaderFileWriter
访问数组ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter
访问字符串StringReaderStringWriter
缓冲流(处理)BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter
操作对象ObjectInputStreamObjectOutputStream

一个流读完了就没有了,就不能在读了

字节流通过InputStreamReader转化为字符流

// 字节流通过InputStreamReader转化为字符流,通过BufferedReader处理流BufferedReader reader = new BufferedReader(new InputStreamReader(tarArchiveInputStream));
String line;
while ((line = reader.readLine()) != null) {list.add(line);
}

字符流通过ByteArrayInputStream转化为字节流

List<String> list = Arrays.asList("Hello", "world!");
StringBuilder builder = new StringBuilder();
list.forEach(item -> {builder.append(item);builder.append("\n");
});
String str = builder.toString();
byteArrayInputStream = new ByteArrayInputStream(str.getBytes());
bufferedInputStream = new BufferedInputStream(byteArrayInputStream);

集合字符串输入文件中

List<String> list = Arrays.asList("Hello", "world!");String str = builder.toString();
File tempFile = File.createTempFile("demo8", ".txt");
// 第一种
StringBuilder builder = new StringBuilder();
list.forEach(item -> {builder.append(item);builder.append("\n");
});
try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) {writer.write(str);
}
// 第二种 
FileUtil.writeLines(list, tempFile, Charset.forName("UTF-8"));

字节流和字符流的输入输出

public class IOUtilsTest {@Testpublic void demo() {try (InputStream inputStream = new FileInputStream(new File("/Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/src/test/resources/a.txt"));FileOutputStream fileOutputStream = new FileOutputStream(new File("/Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/src/test/resources/b.txt"), true)) {byte[] buf = new byte[1024];int len;while ((len = inputStream.read(buf)) != -1) {
//               write(b, off, len)的一般契约是数组b中的一些字节按顺序写入输出流;元素b[off]是写入的第一个字节,
//               b[off+len-1]是该操作写入的最后一个字节。
//               OutputStream的write方法在每个要写入的字节上调用一个参数的write方法fileOutputStream.write(buf, 0, len);}} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}@Testpublic void demo2(){File fileInput = new File("/Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/src/test/resources/a.txt");File fileOutput = new File("/Users/yyyyjinying/demo-file/git/backend/wx-project/wx-official-project/src/test/resources/c.txt");FileReader fileReader = null;FileWriter fileWriter = null;try {fileReader = new FileReader(fileInput);fileWriter = new FileWriter(fileOutput);char[] buf = new char[1024];int len;while((len = fileReader.read(buf)) != -1){fileWriter.write(buf, 0, len);}} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {try {fileReader.close();} catch (IOException e) {throw new RuntimeException(e);}try {fileWriter.close();} catch (IOException e) {throw new RuntimeException(e);}}}}

IOUtils.closeQuietly

可以简化io关闭的代码,

import org.apache.tomcat.util.http.fileupload.IOUtils;
import java.io.StringReader;
import java.io.StringWriter;try {} catch (IOException e) { } finally {if (in != null) {try {in.close();} catch (IOException e) {}}if (out != null) {try {out.close();} catch (IOException e) {}}}       try {} catch (IOException e) { } finally {IOUtils.closeQuietly(in);IOUtils.closeQuietly(out);}       
String content = "字符串";
StringReader reader = new StringReader(content);
StringWriter sw = new StringWriter();
try {//渲染模板 模板名没有取默认值String templateName = map.getOrDefault("templateName", "generator").toString();Template template = new Template(templateName, reader, null, "utf-8");template.process(map, sw);
} catch (Exception e) {e.printStackTrace();throw new RenException("渲染模板失败,请检查模板语法", e);
}content = sw.toString();IOUtils.closeQuietly(reader);
IOUtils.closeQuietly(sw);
return content;

序列化和反序列化

序列化:将对象写入到IO流中,说的简单一点就是将内存模型的对象变成字节数字,可以进行存储和传输;
反序列化:从IO流中恢复对象,将存储在磁盘或者从网络接收的数据恢复成对象模型;
使用场景:所有可在网络上传输的对象都必须是可序列化的,否则会出错;所有需要保存到磁盘的Java对象都必须是可序列化的。
序列化版本号:我们知道,反序列化必须拥有class文件,但随着项目的升级,class文件也会升级,序列化怎么保证升级前后的兼容性呢?​ Java序列化提供了一个``private static final long serialVersionUID` 的序列化版本号,只要版本号相同,即使更改了序列化属性,对象也可以正确被反序列化回来。序列化版本号可自由指定,如果不指定,JVM会根据类信息自己计算一个版本号,这样随着class的升级、代码的修改等因素无法正确反序列化;不指定版本号另一个明显隐患是,不利于jvm间的移植,可能class文件没有更改,但不同jvm可能计算的规则不一样,这样也会导致无法反序列化。
所有需要网络传输的对象都需要实现序列化接口。
对象的类名、实例变量(包括基本类型,数组,对其他对象的引用)都会被序列化;方法、类变量、transient实例变量都不会被序列化。如果想让某个变量不被序列化,使用transient修饰。序列化对象的引用类型成员变量,也必须是可序列化的,否则,会报错。反序列化时必须有序列化对象的class文件。同一对象序列化多次,只有第一次序列化为二进制流,以后都只是保存序列化编号,不会重复序列化。建议所有可序列化的类加上serialVersionUID 版本号,方便项目升级。

/*** user对象通过字节流实现深拷贝* @throws CloneNotSupportedException*/@Testpublic void deepClone() throws IOException, ClassNotFoundException {User user = new User("aa", "bb");user.setDog(new Dog("dog"));// 写出缓存字节数组ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();ObjectOutputStream out = new ObjectOutputStream(byteArrayOutputStream);out.writeObject(user);byte[] bytes = byteArrayOutputStream.toByteArray();// 将缓存字节数组写入程序对象ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);ObjectInputStream in = new ObjectInputStream(byteArrayInputStream);User user1 = (User) in.readObject();// 关闭资源byteArrayInputStream.close();in.close();out.close();byteArrayOutputStream.close();user.setName("xiugai");user.getDog().setName("xigou");System.out.println(user);System.out.println(user1);}@Testpublic void qianClone() throws CloneNotSupportedException {User user = new User("aa", "bb");user.setDog(new Dog("dog"));User user1 = (User) user.clone();user.setName("xiugai");user.getDog().setName("xigou");System.out.println(user);System.out.println(user1);}

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

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

相关文章

【数据结构(五)】递归

文章目录 1. 递归的概念2. 递归能解决什么问题3. 递归的规则4. 递归实际应用案例4.1. 迷宫问题4.2. 八皇后问题4.2.1. 思路分析4.2.1. 代码实现 1. 递归的概念 简单的说: 递归就是方法自己调用自己&#xff0c;每次调用时传入不同的变量。递归有助于编程者解决复杂的问题&…

数据结构 - 堆:TOP-K问题

问题描述 TOP-K问题&#xff1a;即求数据结合中前K个最大的元素或者最小的元素&#xff0c;一般情况下数据量都比较大 比如&#xff1a;专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等 对于Top-K问题&#xff0c;能想到的最简单直接的方式就是排序&#xff0c;但是&…

Linux部署elasticsearch集群

文章目录 一、集群规划二、安装前准备(所有节点操作)创建数据目录修改系统配置文件/etc/sysctl.conf创建用户组设置limits.conf 三、初始化配置(在节点1上操作)下载安装包解压安装包修改jvm.options文件下配置的所占内存修改集群配置文件elasticsearch.yml将安装包传到另外两个…

00后卷王真的很卷吗?

前言 都在传00后躺平、整顿职场&#xff0c;但该说不说&#xff0c;是真的卷&#xff0c;感觉我都要被卷废了... 前段时间&#xff0c;公司招了一个年轻人&#xff0c;其中有一个是00后&#xff0c;工作才一年多&#xff0c;直接跳槽到我们公司&#xff0c;薪资据说有18K&…

Linux学习——模拟实现mybash小程序

目录 一&#xff0c;跟正宗的bash见个面 二&#xff0c;实现一个山寨的bash 1.提示符 2.输入命令与回显命令 3.解析命令 4.执行命令 5.执行逻辑 三&#xff0c;全部代码 一&#xff0c;跟正宗的bash见个面 在这篇文章中&#xff0c;我会写一个myshell小程序。这个小程序…

logback-spring.xml详解

《springboot使用logback日志框架超详细教程》文中&#xff0c;filter中最重要的两个过滤器LevelFilter&#xff08;日志级别精确匹配&#xff09;、ThresholdFilter&#xff08;阈值过滤&#xff09; 的描述非常准确&#xff1a; springboot使用logback日志框架超详细教程_sp…

SQL Server数据库部署

数据库简介 使用数据库的必要性 使用数据库可以高效且条理分明地存储数据&#xff0c;使人们能够更加迅速、方便地管理数据。数据库 具有以下特点。 》可以结构化存储大量的数据信息&#xff0c;方便用户进行有效的检索和访问。 》 可以有效地保持数据信息的一致性&#xff0c…

【Casbin】一篇文章入门Casbin

Casbin Casbin模型基础&#xff08;PERM&#xff09;Policy定义Request定义MatchersEffect ACL模型RBAC模型Go语言实战使用前先下载casbin包新建一个Casbin enforcer判断是否能通过增加Policy删除Policy更新Policy获取Policy Casbin 权限管理在几乎每个系统中都是必备的模块。…

java设计模式学习之【桥接模式】

文章目录 引言桥接模式简介定义与用途&#xff1a;实现方式 使用场景优势与劣势桥接模式在Spring中的应用绘图示例代码地址 引言 想象你正在开发一个图形界面应用程序&#xff0c;需要支持多种不同的窗口操作系统。如果每个系统都需要写一套代码&#xff0c;那将是多么繁琐&am…

【vue-router】useRoute 和 useRouter 的区别

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

一起学docker系列之十四Dockerfile微服务实践

目录 1 前言2 创建微服务模块2.1 **创建项目模块**2.2 **编写业务代码** 3 编写 Dockerfile4 构建 Docker 镜像5 运行 Docker 容器6 测试微服务7 总结8 参考地址 1 前言 微服务架构已经成为现代软件开发中的一种重要方式。而 Docker 提供了一种轻量级、便携式的容器化解决方案…

ESP32和ESP8266的ESP-MESH

ESP32和ESP8266的ESP-MESH 功能介绍一、介绍ESP-MESH二、安装painlessMesh库三、ESP-MESH基本示例&#xff08;广播消息&#xff09;四、示范 功能介绍 了解如何使用ESP-MESH网络协议通过ESP32和ESP8266 NodeMCU板构建网状网络。 ESP-MESH允许多个设备&#xff08;节点&#x…

群晖NAS配置之自有服务器frp实现内网穿透

什么是frp frp 是一个专注于内网穿透的高性能的反向代理应用&#xff0c;支持 TCP、UDP、HTTP、HTTPS 等多种协议&#xff0c;且支持 P2P 通信。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。今天跟大家分享一下frp实现内网穿透 为什么使用 frp &a…

基于瑞芯微rk3588+寒武纪 | 38TOPS INT8算力的AI边缘计算盒子,智能安防、智慧工地、智慧城管、智慧油站

边缘计算盒子 瑞芯微rk3588寒武纪 | 38TOPS INT8算力 ● 采用 Big-Little 大小核架构&#xff0c;搭载四核 A76四核 A55&#xff0c;CPU主频高达 2.4GHz &#xff0c;提供1MB L2 Cache 和 3MB L3 &#xff0c;Cache提供更强的 CPU 运算能力。 ● 高性能四核 Mali-G610 GPU&a…

i++和++i的区别

i和i的区别 一、基本概念 两者的作用都是自增加1。 单独拿出来说的话&#xff0c;i和i&#xff0c;效果都是一样的&#xff0c;就是ii1 public static void main(String[] args) {int i 0;i;System.out.println(i);}public static void main(String[] args) {int i 0;i;Sys…

【开源】基于JAVA语言的校园电商物流云平台

项目编号&#xff1a; S 034 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S034&#xff0c;文末获取源码。} 项目编号&#xff1a;S034&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 商品数据模块2.3 快…

FH Admin Shiro反序列化漏洞复现

0x01 产品简介 FH Admin 是一款 java 快速开发平台。 0x02 漏洞概述 FH Admin CMS 存在 shiro 反序列化漏洞&#xff0c;该漏洞源于软件存在硬编码的 shiro-key&#xff0c;攻击者可利用该 key 生成恶意的序列化数据&#xff0c;在服务器上执行任意代码&#xff0c;执行系统命…

python自动化第二篇——合并ppt

简述 python合并ppt的方法有很多&#xff0c;但网上常说的python-pptx的方法&#xff0c;我用不了&#xff0c;这里我用了一个python-office的库。但又两个缺点&#xff0c;第一个生成的文档在你的用户名下的文档里&#xff0c;第二个是名字随机。 import office import os im…

vue3-vite-ts:编写Rollup插件并使用 / 优化构建过程

一、vue3-vite-ts项目&#xff0c;编写Rollup插件并使用的意义 在使用Vue3 Vite TypeScript这种技术栈时&#xff0c;可以使用Rollup插件来优化构建过程&#xff0c;例如使用rollup-plugin-typescript2插件来编译TypeScript代码&#xff0c;使用rollup-plugin-vue插件来处理…

【开源】基于Vue+SpringBoot的康复中心管理系统

项目编号&#xff1a; S 056 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S056&#xff0c;文末获取源码。} 项目编号&#xff1a;S056&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 普通用户模块2.2 护工模块2.3 管理员…