MinIO讲解和java应用案例示范
一、MinIO 基本概念
1.1 什么是 MinIO?
MinIO 是一个高性能的对象存储服务器,专为云原生应用设计。它支持 Amazon S3 API,因此可以与现有的 S3 客户端和工具集成。MinIO 主要用于存储非结构化数据,如图片、视频、备份文件和日志等,适合大数据分析、机器学习、以及容器化环境中的数据存储需求。
特点:
- 高性能:通过高效的网络 I/O 和并发处理,MinIO 能够在普通硬件上实现极高的吞吐量。
- 简单易用:轻量级的设计使得部署和管理变得简单,适合开发者快速上手。
- 兼容性:完全兼容 Amazon S3 API,支持广泛的工具和库。
- 可扩展性:支持水平扩展,能够在需求增加时轻松添加更多存储节点。
1.2 MinIO 与传统存储的区别
与传统存储系统相比,MinIO 提供了许多显著的优势:
- 对象存储 vs 文件存储:
- 对象存储(如 MinIO)将数据视为对象,而不仅仅是文件,数据通过唯一的对象 ID 进行访问。相比之下,文件存储使用文件路径和目录结构。
- 对象存储支持更大的数据规模,适合存储大量非结构化数据,适合大数据和云计算环境。
- 对象存储 vs 块存储:
- 块存储(如 Amazon EBS、Azure Disk)用于数据库和应用程序,需要更低延迟和高性能的块级访问。对象存储则适合处理大文件和海量数据,优化了存储和检索过程。
- 块存储的定价模式通常更复杂,而对象存储则基于存储量和请求计费,通常更具成本效益。
二、MinIO 架构与组件
2.1 简述 MinIO 的架构设计
MinIO 的架构设计围绕高可用性和高性能展开,其核心组件包括:
- 存储节点:每个节点负责存储数据和处理请求。MinIO 可以在多个节点上运行以实现高可用性。
- 元数据存储:负责管理存储对象的元数据,包括对象的名称、大小、创建时间、权限等信息。
- 负载均衡:MinIO 内置负载均衡机制,能够自动将请求分配到不同的存储节点,提高系统吞吐量。
2.2 MinIO 如何保证数据的高可用性和一致性?
MinIO 通过以下机制确保数据的高可用性和一致性:
- 数据冗余:支持通过在多个节点之间复制数据来实现冗余存储,以防止单点故障。
- 纠删码:MinIO 使用纠删码技术对数据进行编码,将数据分割为多个片段,并在多个节点上存储这些片段,确保即使某些节点失效也能恢复数据。
- 强一致性:MinIO 通过使用分布式共识算法(如 Raft)来实现数据的强一致性,确保每次写入和读取都是一致的。
三、MinIO 在 Java 中的使用
3.1 如何在 Java 项目中集成 MinIO?
要在 Java 项目中使用 MinIO,首先需要引入 MinIO Java SDK 的依赖。在 Maven 项目的 pom.xml
中添加以下依赖:
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.0.0</version>
</dependency>
3.2 使用 MinIO Java SDK 实现文件上传和下载的核心代码步骤
文件上传示例
import io.minio.MinioClient;
import io.minio.PutObjectArgs;import java.io.File;public class MinioUpload {public static void main(String[] args) throws Exception {MinioClient minioClient = MinioClient.builder().endpoint("https://play.min.io").credentials("YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY").build();minioClient.putObject(PutObjectArgs.builder().bucket("mybucket").object("myfile.txt").filename("/path/to/myfile.txt").build());System.out.println("File uploaded successfully.");}
}
文件下载示例
import io.minio.MinioClient;
import io.minio.GetObjectArgs;
import io.minio.PutObjectArgs;import java.io.InputStream;public class MinioDownload {public static void main(String[] args) throws Exception {MinioClient minioClient = MinioClient.builder().endpoint("https://play.min.io").credentials("YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY").build();InputStream stream = minioClient.getObject(GetObjectArgs.builder().bucket("mybucket").object("myfile.txt").build());// 处理流,例如保存到文件// ...System.out.println("File downloaded successfully.");}
}
3.3 如何在 Java 中设置 MinIO 的访问权限?
MinIO 支持基于用户的访问控制,您可以通过设置桶策略来定义访问权限。以下是如何在 Java 中设置桶的访问权限的示例:
import io.minio.MinioClient;
import io.minio.SetBucketPolicyArgs;public class MinioSetPolicy {public static void main(String[] args) throws Exception {MinioClient minioClient = MinioClient.builder().endpoint("https://play.min.io").credentials("YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY").build();String policy = "{ \"Version\": \"2012-10-17\", \"Statement\": [" +"{ \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"*\" }, " +"\"Action\": \"s3:GetObject\", \"Resource\": \"arn:aws:s3:::mybucket/*\" }]}";minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket("mybucket").config(policy).build());System.out.println("Bucket policy set successfully.");}
}
四、MinIO 存储桶操作
在 MinIO 中,存储桶是用来存储对象的容器,进行有效的存储管理至关重要。以下是如何使用 MinIO Java SDK 来创建、删除和查询存储桶,以及如何管理存储桶的生命周期。
4.1 在 MinIO 中如何创建、删除和查询存储桶?
4.1.1 创建存储桶
使用 MinIO Java SDK 创建存储桶的基本步骤如下:
import io.minio.MinioClient;
import io.minio.MakeBucketArgs;
import io.minio.BucketExistsArgs;
import java.util.Objects;public class MinioCreateBucket {public static void main(String[] args) {try {MinioClient minioClient = MinioClient.builder().endpoint("https://play.min.io").credentials("YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY").build();// 检查存储桶是否存在boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket("mybucket").build());if (!isExist) {// 创建存储桶minioClient.makeBucket(MakeBucketArgs.builder().bucket("mybucket").build());System.out.println("Bucket created successfully.");} else {System.out.println("Bucket already exists.");}} catch (Exception e) {System.out.println("Error occurred: " + e.getMessage());}}
}
4.1.2 删除存储桶
删除存储桶的步骤如下:
import io.minio.MinioClient;
import io.minio.RemoveBucketArgs;public class MinioDeleteBucket {public static void main(String[] args) {try {MinioClient minioClient = MinioClient.builder().endpoint("https://play.min.io").credentials("YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY").build();// 删除存储桶minioClient.removeBucket(RemoveBucketArgs.builder().bucket("mybucket").build());System.out.println("Bucket deleted successfully.");} catch (Exception e) {System.out.println("Error occurred: " + e.getMessage());}}
}
4.1.3 查询存储桶
查询存储桶的基本示例:
import io.minio.MinioClient;public class MinioListBuckets {public static void main(String[] args) {try {MinioClient minioClient = MinioClient.builder().endpoint("https://play.min.io").credentials("YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY").build();// 列出所有存储桶minioClient.listBuckets().forEach(bucket -> {System.out.println("Bucket name: " + bucket.name());});} catch (Exception e) {System.out.println("Error occurred: " + e.getMessage());}}
}
4.2 存储桶的生命周期管理在 Java 中如何实现?
MinIO 支持存储桶的生命周期管理,可以设置对象的过期策略,以便在不再需要时自动删除。下面是如何设置存储桶生命周期策略的示例:
4.2.1 设置存储桶生命周期策略
import io.minio.MinioClient;
import io.minio.SetBucketLifecycleArgs;public class MinioSetLifecycle {public static void main(String[] args) {try {MinioClient minioClient = MinioClient.builder().endpoint("https://play.min.io").credentials("YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY").build();// 定义生命周期策略String lifecycleConfig = "{ \"Rules\": [" +"{ \"ID\": \"expire-objects\"," +" \"Status\": \"Enabled\"," +" \"Expiration\": { \"Days\": 30 }" +"}]}";// 设置生命周期minioClient.setBucketLifecycle(SetBucketLifecycleArgs.builder().bucket("mybucket").config(lifecycleConfig).build());System.out.println("Bucket lifecycle set successfully.");} catch (Exception e) {System.out.println("Error occurred: " + e.getMessage());}}
}
在这个示例中,我们定义了一个规则来设置存储桶中的对象在创建后 30 天自动过期。
五、性能与优化
MinIO 作为高性能的对象存储解决方案,虽然设计上已经考虑了高效性,但在使用大量小文件时,性能仍然可能受到影响。下面是一些优化建议。
5.1 在使用 MinIO 存储大量小文件时,如何优化性能?
5.1.1 从 Java 应用程序角度
- 批量操作:尽量将小文件合并为较大的文件进行上传,减少 API 调用次数。
- 异步上传:使用异步或多线程方式上传文件,提高上传效率。
- 缓存机制:实现缓存机制,减少重复读取操作。
示例:使用多线程上传文件
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class MinioMultiThreadUpload {public static void main(String[] args) {try {MinioClient minioClient = MinioClient.builder().endpoint("https://play.min.io").credentials("YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY").build();ExecutorService executor = Executors.newFixedThreadPool(10);for (int i = 0; i < 100; i++) {int fileIndex = i;executor.submit(() -> {try {minioClient.putObject(PutObjectArgs.builder().bucket("mybucket").object("file" + fileIndex + ".txt").filename("/path/to/file" + fileIndex + ".txt").build());System.out.println("Uploaded file" + fileIndex);} catch (Exception e) {System.out.println("Error uploading file" + fileIndex + ": " + e.getMessage());}});}executor.shutdown();} catch (Exception e) {System.out.println("Error occurred: " + e.getMessage());}}
}
5.1.2 从 MinIO 配置角度
- 调整存储后端:使用 SSD 而非 HDD 来提高存储性能。
- 优化 MinIO 配置:调整
--storage-class
参数来优化对象存储性能,根据实际使用情况选择合适的存储类别。 - 启用压缩:在配置 MinIO 时启用压缩功能,能够减少存储占用和提高传输速度。
5.2 如果遇到 MinIO 性能瓶颈,有哪些可能的排查方向和优化方法?
- 网络性能:
- 检查网络延迟,使用
ping
和traceroute
工具确认网络路径和延迟。 - 确保网络带宽充足,避免高流量时段造成的瓶颈。
- 检查网络延迟,使用
- 存储硬件:
- 监测存储硬件的性能,确保没有 I/O 阻塞或故障。
- 使用 RAID 配置来提升数据读写性能。
- 软件配置:
- 检查 MinIO 的日志文件,确认是否有错误或警告信息。
- 优化 MinIO 的配置参数,例如
MINIO_API
和MINIO_STORAGE_CLASS
,以适应实际应用场景。
- 监控与分析:
- 使用监控工具(如 Prometheus 和 Grafana)监测 MinIO 的性能指标,及时识别问题。
- 定期分析存储使用情况,评估数据分布和访问模式,以进行优化。
六、Spring Boot 整合 MinIO
将 MinIO 与 Spring Boot 应用集成,可以实现高效的对象存储和管理。下面将介绍几种常见的整合方法,并给出应用案例。
6.1 使用 Spring Boot Starter 集成 MinIO
Spring Boot Starter 是一种简化开发的方式,可以方便地将 MinIO 集成到 Spring Boot 项目中。
6.1.1 添加依赖
在 pom.xml
文件中添加 MinIO 和 Spring Boot Starter 的依赖:
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.3.0</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency>
6.1.2 配置 MinIO 属性
在 application.properties
或 application.yml
中配置 MinIO 的连接信息:
minio.url=https://play.min.io
minio.access-key=YOUR-ACCESSKEYID
minio.secret-key=YOUR-SECRETACCESSKEY
6.1.3 创建 MinIO 客户端 Bean
在 Spring Boot 的配置类中创建 MinIO 客户端的 Bean:
import io.minio.MinioClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MinioConfig {@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint("https://play.min.io").credentials("YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY").build();}
}
6.2 应用案例:使用 Spring Boot 实现文件上传与下载
下面是一个简单的示例,展示如何使用 Spring Boot 实现文件的上传与下载功能。
6.2.1 创建控制器
创建一个 FileController
来处理文件的上传和下载请求:
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.GetObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;@RestController
@RequestMapping("/files")
public class FileController {@Autowiredprivate MinioClient minioClient;@PostMapping("/upload")public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {try {String bucketName = "mybucket";// 检查存储桶是否存在if (!minioClient.bucketExists(bucketName)) {minioClient.makeBucket(bucketName);}// 上传文件minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(file.getOriginalFilename()).stream(file.getInputStream(), file.getSize(), -1).build());return ResponseEntity.ok("File uploaded successfully: " + file.getOriginalFilename());} catch (Exception e) {return ResponseEntity.status(500).body("Error uploading file: " + e.getMessage());}}@GetMapping("/download/{filename}")public ResponseEntity<InputStream> downloadFile(@PathVariable String filename) {try {String bucketName = "mybucket";InputStream stream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(filename).build());return ResponseEntity.ok().body(stream);} catch (Exception e) {return ResponseEntity.status(500).body(null);}}
}
6.2.2 配置 Spring Boot 应用
在 application.properties
文件中添加 MinIO 的配置:
minio.url=https://play.min.io
minio.access-key=YOUR-ACCESSKEYID
minio.secret-key=YOUR-SECRETACCESSKEY
6.2.3 运行应用
启动 Spring Boot 应用,然后通过 Postman 或其他 API 客户端进行测试。
- 上传文件:使用 POST 请求上传文件至
/files/upload
,选择文件进行上传。 - 下载文件:使用 GET 请求访问
/files/download/{filename}
来下载指定的文件。
相关文章:

MinIO讲解和java应用案例示范
一、MinIO 基本概念 1.1 什么是 MinIO? MinIO 是一个高性能的对象存储服务器,专为云原生应用设计。它支持 Amazon S3 API,因此可以与现有的 S3 客户端和工具集成。MinIO 主要用于存储非结构化数据,如图片、视频、备份文件和日志…...

区块链技术与应用 【全国职业院校技能大赛国赛题目解析】第1套 区块链系统设计与运维部分
模块一:区块链产品方案设计及系统运维(35分) 选手完成本模块的任务后,将任务中设计结果、运行代码、运行结果等截图粘贴至客户端桌面【区块链技术应用赛\重命名为工位号\模块一提交结果.docx】中对应的任务序号下。 前述: 我们收到答案后,将针对比赛的答案和样题进行解…...

yaml文件编写
Kubernetes 支持YAML和JSON格式管理资源 JSON 格式:主要用于 api 接口之间消息的传递 YAML 格式;用于配置和管理,YAML是一种简洁的非标记性语言,内容格式人性化容易读懂 一,yaml语法格式 1.1 基本语法规则 使用空格进行缩进(不使用制表符࿰…...

TOEIC 词汇专题:娱乐休闲篇
TOEIC 词汇专题:娱乐休闲篇 在娱乐和休闲活动中,我们会接触到许多特定的词汇。这些词汇涉及到活动入场、观众互动、评论等各个方面,帮助你在相关场景中更加自如。 1. 入场和观众 一些常用词汇帮助你轻松应对观众与入场管理相关的场景&#…...

驱动TFT-1.44寸屏(ST7735)显示器
目录 一、驱动芯片介绍 二、驱动方式 三、主函数main运行 四、完整代码下载 TFT1.44寸屏,搭配ST7735驱动芯片,是一种专为小型电子设备设计的彩色液晶显示解决方案。该屏幕采用薄膜晶体管(TFT)技术,能够实现高亮度、…...

鸿蒙HarmonyOS NEXT一多适配技术方案
鸿蒙一多是什么 HarmonyOS 系统面向多终端提供了“一次开发,多端部署”(后文中简称为“一多”)的能力,让开发者可以基于一种设计,高效构建多端可运行的应用。 一套代码工程,一次开发上架,多端按…...

golang 中map使用的一些坑
golang 中map使用的一些坑 1、使用map[string]interface{},类型断言[]int失败 接收下游的数据是用json转为map[string]any go a : "{\"a\":\"1\",\"b\":[123]}" var marshal map[string]any json.Unmarshal([]byte(a), &…...

cordova 离线打包Android -Linux
背景 已有 cordova 运行环境的docker镜像; 需要在离线环境下执行 cordova 从创建项目到构建安装包一系列命令,最终生成 apk 文件。 方案 先在有网环境(最好与离线环境的OS一致)走一遍 cordova 创建打包工程、添加插件、添加平…...

【python】OpenCV—findContours(4.3)
文章目录 1、功能描述2、代码实现3、完整代码4、结果展示5、涉及到的库函数5.1、cv2.Canny5.2 cv2.boxPoints 6、参考 1、功能描述 找出图片中的轮廓,拟合轮廓外接椭圆和外接矩阵 2、代码实现 导入必要的库,固定好随机种子 import cv2 as cv import …...

前端通过nginx部署一个本地服务的方法
前端通过nginx部署一个本地服务的方法: 1.下载ngnix nginx 下载完成后解压缩后运行nginx.exe文件 2.打包你的前端项目文件 yarn build 把生成的dist文件复制出来,替换到nginx的html文件下 3.配置conf目录的nginx.conf文件 主要配置server监听 ser…...

Linux:防火墙和selinux对服务的影响
1-1selinux 1-1 SELinux是对程序、文件等权限设置依据的一个内核模块。由于启动网络服务的也是程序,因此刚好也 是能够控制网络服务能否访问系统资源的一道关卡。 1-2 SELinux是通过MAC的方式来控制管理进程,它控制的主体是进程,而目标则是…...

从 vue 源码看问题 — vue 如何进行异步更新?
前言 在上一篇 如何理解 vue 响应式? 中,了解到响应式其实是通过 Observer 类中调用 defineReactive() 即 Object.defineProperty() 方法为每个目标对象的 key(key 对应的 value 为非数组的) 设置 getter 和 setter 实现拦截&…...

【go从零单排】go中的基本数据类型和变量
Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 基本类型 go中的string、int、folat都可以用连接boolen可以用逻辑表达式计算 package mainimport "fmt&quo…...

标签之文字排版,图片,链接,音视频(HTML) 基础版
目录 标签之文字排版,图片,链接,音视频知识点: 练习题一: 效果: 练习题二: 效果: 标签之文字排版,图片,链接,音视频知识点: 超文本:链接 标记:标签<> 双标签 单标签 <br>//换行 <hr>//水平线 向后tab 向前shifttab html注释<!----> css /**/ …...

基于SpringBoot+Gpt个人健康管家管理系统【提供源码+答辩PPT+参考文档+项目部署】
作者简介:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容:🌟Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…...

十四届蓝桥杯STEMA考试Python真题试卷第二套第一题
来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第一题 题目描述: 给定一个字符串,输出字符串中最后一个字符。 输入描述: 输入一个字符串 输出描述: 输出字符串中最后一个字符 样例输入: hgf 样…...

【Windows修改Docker Desktop(WSL2)内存分配大小】
记录一下遇到使用Docker Desktop占用内存居高不下的问题 自从使用了Docker Desktop,电脑基本每天都需要重启,内存完全不够用,从16g扩展到24,然后到40G,还是不够用;打开Docker Desktop 运行时间一长&#x…...

阿里云-部署CNI flannel集群网络
环境 1.一台阿里云作为k8s-master:8.130.XXX.231(阿里云私有IP) 2.Vmware 两个虚拟机分别作为 k8s-node1:192.168.40.131 k8s-node2:192.168.40.131 3.安装Docker 部署过程 k8s-master,k8s-node1,k8s-node2 初始操作 # 关闭防火墙 systemctl stop fi…...

favicon是什么文件?如何制作网站ico图标?
一般我们做网站的话,都会制作一个独特的ico图标,命名为favicon.ico。这个ico图标一般会出现在浏览器网页标题前面。如下图红色箭头所示: 部分博客导航大全也会用到所收录网站的ico图标。比如boke123导航新收录的网站就不再使用网站首页缩略图…...

Linux云计算个人学习总结(一)
windows计算机基础 一、概述 1.计算机基本原则:计算机是执行输入、运算、输出的原则。软件是指命令和数据的结合,计算机中所有的内容皆为数字。 2.计算机的类型 计算器 手机 cps等都属于计算机。 3.计算机的发展 第一代计算机电子管时代&…...

DCRNN解读(论文+代码)
一、引言 作者首先提出:空间结构是非欧几里得且有方向性的,未来的交通速度受下游交通影响大于上游交通。虽然卷积神经网络(CNN)在部分研究中用于建模空间相关性,但其主要适用于欧几里得空间(例如二维图像&a…...

雷池社区版新版本功能防绕过人机验证解析
前两天,2024.10.31,雷池社区版更新7.1版本,其中有一个功能,新增请求防重放 更新记录:hhttps://docs.waf-ce.chaitin.cn/zh/%E7%89%88%E6%9C%AC%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95 仔细研究了这个需求,…...

一文详解开源ETL工具Kettle!
一、Kettle 是什么 Kettle 是一款开源的 ETL(Extract - Transform - Load)工具,用于数据抽取、转换和加载。它提供了一个可视化的设计环境,允许用户通过简单的拖拽和配置操作来构建复杂的数据处理工作流,能够处理各种数…...

《IMM交互式多模型滤波MATLAB实践》专栏目录,持续更新……
专栏链接:https://blog.csdn.net/callmeup/category_12816762.html 专栏介绍 关于IMM的例程 双模型EKF: 【逐行注释】基于CV/CT模型的IMM|MATLAB程序|源代码复制后即可运行,无需下载三模型EKF: 【matlab代码】3个模型的IMM例程&…...

解决数据集中xml文件类别标签的首字母大小写不一致问题
import os import xml.etree.ElementTree as ET# 指定要处理的 XML 文件夹路径 xml_folder_path rD:\CVproject\ultralytics-main\datatrans\Annotationsdef capitalize_first_letter_in_xml(xml_file):# 解析 XML 文件tree ET.parse(xml_file)root tree.getroot()# 遍历所有…...

手边酒店多商户版V2源码独立部署_博纳软云
新版采用laraveluniapp开发,为更多平台小程序开发提供坚实可靠的底层架构基础。后台UI全部重写,兼容手机端管理。 全新架构、会员卡、钟点房、商城、点餐、商户独立管理...

32位汇编——通用寄存器
通用寄存器 什么是寄存器呢? 计算机在三个地方可以存储数据,第一个是把数据存到CPU中,第二个把数据存到内存中,第三个把数据存到硬盘上。 那这个所谓的寄存器,就是CPU中用来存储数据的地方。那这个寄存器有多大呢&a…...

vue3项目中实现el-table分批渲染表格
开篇 因最近工作中遇到了无分页情景下页面因大数据量卡顿的问题,在分别考虑并尝试了懒加载、虚拟滚动、分批渲染等各个方法后,最后决定使用分批渲染来解决该问题。 代码实现 表格代码 <el-table :data"currTableData"borderstyle"wi…...

开源办公软件 ONLYOFFICE 深入探索
文章目录 引言1. ONLYOFFICE 创建的背景1. 1 ONLYOFFICE 项目启动1. 2 ONLYOFFICE 的发展历程 2. 核心功能介绍2. 1 桌面编辑器2. 1. 1 文档2. 1. 2 表格2. 1. 3 幻灯片 2. 2 协作空间2. 3 文档编辑器 - 本地部署版 3. 技术介绍4. 安装5. 优势与挑战6. 个人体验7. 强大但不止于…...

原生鸿蒙应用市场:开发者的新机遇与深度探索
文章目录 自动化检测前移:提升开发效率与质量的新利器数据服务:数据驱动的精细化运营助手测试服务:保障应用质量的关键环节应用加密:保护应用安全与权益的利器从开发到运营的全方位支持写在最后 2024年10月22日,华为在…...