使用SpringBoot集成FastDFS

使用SpringBoot集成FastDFS

这篇文章我们介绍如何使用 Spring Boot 将文件上传到分布式文件系统 FastDFS 中。

1、FastDFS

FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问

(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网

站、视频网站等等。

FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,

使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文件上传、下载,通过

Tracker server 调度最终由 Storage server 完成文件上传和下载。

Tracker server 作用是负载均衡和调度,通过 Tracker server 在文件上传时可以根据一些策略找到Storage server

提供文件上传服务。可以将 tracker 称为追踪服务器或调度服务器。Storage server 作用是文件存储,客户端上传

的文件最终存储在 Storage 服务器上,Storageserver 没有实现自己的文件系统而是利用操作系统的文件系统来管

理文件。可以将storage称为存储服务器。

在这里插入图片描述

上传流程

在这里插入图片描述

客户端上传文件后存储服务器将文件 ID 返回给客户端,此文件 ID 用于以后访问该文件的索引信息。文件索引信

息包括:组名,虚拟磁盘路径,数据两级目录,文件名。

在这里插入图片描述

组名:文件上传后所在的 storage 组名称,在文件上传成功后有storage 服务器返回,需要客户端自行保存。

虚拟磁盘路径:storage 配置的虚拟路径,与磁盘选项store_path*对应。如果配置了

store_path0 则是 M00,如果配置了 store_path1 则是 M01,以此类推。

数据两级目录:storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。

文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器 IP 地址、文件创建

时间戳、文件大小、随机数和文件拓展名等信息。

2、docker 安装 FastDFS

2.1 查找Docker Hub上的fastdfs镜像

$ docker search fastdfs

在这里插入图片描述

2.2 拉取镜像

# 拉取最新版本
$ docker pull delron/fastdfs

在这里插入图片描述

2.3 查看镜像

$ docker images

在这里插入图片描述

2.4 使用docker镜像构建tracker容器

tracker容器跟踪服务器,起到调度的作用。

$ docker run -dti --network=host --name tracker -v /var/fdfs/tracker:/var/fdfs -v /etc/localtime:/etc/localtime delron/fastdfs tracker

2.5 使用docker镜像构建storage容器

storage容器存储服务器,提供容量和备份服务。

$ docker run -dti --network=host --name storage -e TRACKER_SERVER=192.168.56.1:22122 -v /var/fdfs/storage:/var/fdfs -v /etc/localtime:/etc/localtime delron/fastdfs storage

TRACKER_SERVER=本机的ip地址:22122,本机ip地址不要使用127.0.0.1

进入storage容器,到storage的配置文件中配置http访问的端口,配置文件在/etc/fdfs目录下的

storage.conf

在这里插入图片描述

默认端口是8888,也可以不进行更改。

如果重启后无法启动的话,可能是报下面错误了:

tail: cannot open '/var/fdfs/logs/storaged.log' for reading: No such file or directory

手动创建 vi /var/fdfs/logs/storaged.log 文件即可

2.6 配置nginx

进入storage,配置nginx,在/usr/local/nginx目录下,修改nginx.conf文件,默认配置不修改也可以

在这里插入图片描述

2.7 测试上传文件

使用web模块进行文件的上传,将文件上传至FastDFS文件系统

将一张照片(test.png)放置在/var/fdfs/storage目录下:

在这里插入图片描述

进入storage容器,进入/var/fdfs目录,运行下面命令:

/usr/bin/fdfs_upload_file /etc/fdfs/client.conf test.png

此时将该图片已上传至文件系统,并在执行该语句后返回图片存储的uri:

在这里插入图片描述

通过url访问 http://192.168.56.1:8888/group1/M00/00/00/CqACD1z7SEuAXrIqAA1eBLGVLow034.png,即

可查看到图片。

2.8 开放端口

$ firewall-cmd --zone=public --permanent --add-port=8888/tcp
$ firewall-cmd --zone=public --permanent --add-port=22122/tcp
$ firewall-cmd --zone=public --permanent --add-port=23000/tcp

重启防火墙

$ systemctl restart firewalld

2.9 开启启动容器

$ docker update --restart=always tracker
$ docker update --restart=always storage

2.10 常见问题

storage 无法启动

运行 docker container start storage 无法启动,进行如下操作即可:

可以删除/var/fdfs/storage/data目录下的fdfs_storaged.pid 文件,然后重新运行storage。

4、SpringBoot整合FastDFS

4.1 pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.0.RELEASE</version></parent><groupId>com.example</groupId><artifactId>spring-boot-fastdfs</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-fastdfs</name><description>spring-boot-fastDFS</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><dependency><groupId>org.csource</groupId><artifactId>fastdfs-client-java</artifactId><version>1.27-SNAPSHOT</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

加入了fastdfs-client-java包,用来调用 FastDFS 相关的 API。

4.2 配置文件

resources 目录下添加 fdfs_client.conf文件

connect_timeout = 60
network_timeout = 60
charset = UTF-8
http.tracker_http_port = 8080
tracker_server = 192.168.79.113:22122
  • connect_timeout:连接超时时间,单位为秒。

  • network_timeout:通信超时时间,单位为秒。发送或接收数据时。假设在超时时间后还不能发送或接收数

    据,则本次网络通信失败。

  • charset: 字符集。

  • http.tracker_http_port:tracker的http端口。

  • tracker_server: tracker服务器IP和端口设置。

详细内容参考:[fastdfs-client-java] https://github.com/happyfish100/fastdfs-client-java

resources 目录下添加 application.properties文件

# max-file-size是单个文件大小
spring.servlet.multipart.max-file-size=10MB
# max-request-size是设置总上传的数据大小
spring.servlet.multipart.max-request-size=10MB

4.3 封装 FastDFS 上传工具类

封装FastDFSFile,文件基础信息包括文件名、内容、文件类型、作者等。

package com.example.fastdfs;/*** @author zhangshixing*/
public class FastDFSFile {/*** 文件名字*/private String name;/*** 文件内容*/private byte[] content;/*** 文件扩展名*/private String ext;/*** 文件MD5摘要值*/private String md5;/*** 文件创建作者*/private String author;public FastDFSFile(String name, byte[] content, String ext, String height,String width, String author) {super();this.name = name;this.content = content;this.ext = ext;this.author = author;}public FastDFSFile(String name, byte[] content, String ext) {super();this.name = name;this.content = content;this.ext = ext;}public String getName() {return name;}public void setName(String name) {this.name = name;}public byte[] getContent() {return content;}public void setContent(byte[] content) {this.content = content;}public String getExt() {return ext;}public void setExt(String ext) {this.ext = ext;}public String getMd5() {return md5;}public void setMd5(String md5) {this.md5 = md5;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}
}

封装 FastDFSClient 类,包含常用的上传、下载、删除等方法。

首先在类加载的时候读取相应的配置信息,并进行初始化。

package com.example.fastdfs;import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;/*** @author zhangshixing*/
public class FastDFSClient {private static Logger logger = LoggerFactory.getLogger(FastDFSClient.class);/**** 初始化tracker信息*/static {try {String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();ClientGlobal.init(filePath);} catch (Exception e) {logger.error("FastDFS Client Init Fail!", e);}}/***** 文件上传* @param file : 要上传的文件信息封装->FastDFSFile* @return String[]*          1:文件上传所存储的组名*          2:文件存储路径*/public static String[] upload(FastDFSFile file) {logger.info("File Name: " + file.getName() + "File Length:" + file.getContent().length);NameValuePair[] meta_list = new NameValuePair[1];meta_list[0] = new NameValuePair("author", file.getAuthor());long startTime = System.currentTimeMillis();String[] uploadResults = null;StorageClient storageClient = null;try {storageClient = getTrackerClient();uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);} catch (IOException e) {logger.error("IO Exception when uploadind the file:" + file.getName(), e);} catch (Exception e) {logger.error("Non IO Exception when uploadind the file:" + file.getName(), e);}logger.info("upload_file time used:" + (System.currentTimeMillis() - startTime) + " ms");if (uploadResults == null && storageClient != null) {logger.error("upload file fail, error code:" + storageClient.getErrorCode());}String groupName = uploadResults[0];String remoteFileName = uploadResults[1];logger.info("upload file successfully!!!" + "group_name:" + groupName + ", remoteFileName:" + " " + remoteFileName);return uploadResults;}/**** 获取文件信息* @param groupName:组名* @param remoteFileName:文件存储完整名*/public static FileInfo getFile(String groupName, String remoteFileName) {try {StorageClient storageClient = getTrackerClient();return storageClient.get_file_info(groupName, remoteFileName);} catch (IOException e) {logger.error("IO Exception: Get File from Fast DFS failed", e);} catch (Exception e) {logger.error("Non IO Exception: Get File from Fast DFS failed", e);}return null;}/**** 文件下载* @param groupName:组名* @param remoteFileName:文件存储完整名* @return*/public static InputStream downFile(String groupName, String remoteFileName) {try {StorageClient storageClient = getTrackerClient();byte[] fileByte = storageClient.download_file(groupName, remoteFileName);InputStream ins = new ByteArrayInputStream(fileByte);return ins;} catch (IOException e) {logger.error("IO Exception: Get File from Fast DFS failed", e);} catch (Exception e) {logger.error("Non IO Exception: Get File from Fast DFS failed", e);}return null;}/**** 文件删除实现* @param groupName:组名* @param remoteFileName:文件存储完整名*/public static void deleteFile(String groupName, String remoteFileName)throws Exception {StorageClient storageClient = getTrackerClient();int i = storageClient.delete_file(groupName, remoteFileName);logger.info("delete file successfully!!!" + i);}/**** 获取组信息* @param groupName :组名*/public static StorageServer[] getStoreStorages(String groupName)throws IOException {TrackerClient trackerClient = new TrackerClient();TrackerServer trackerServer = trackerClient.getConnection();return trackerClient.getStoreStorages(trackerServer, groupName);}/**** 根据文件组名和文件存储路径获取Storage服务的IP、端口信息* @param groupName :组名* @param remoteFileName :文件存储完整名*/public static ServerInfo[] getFetchStorages(String groupName,String remoteFileName) throws IOException {TrackerClient trackerClient = new TrackerClient();TrackerServer trackerServer = trackerClient.getConnection();return trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);}/**** 获取Tracker服务地址*/public static String getTrackerUrl() throws IOException {return "http://" + getTrackerServer().getInetSocketAddress().getHostString() + ":" + ClientGlobal.getG_tracker_http_port() + "/";}/**** 获取StorageClient* @return* @throws Exception*/private static StorageClient getTrackerClient() throws IOException {TrackerServer trackerServer = getTrackerServer();StorageClient storageClient = new StorageClient(trackerServer, null);return storageClient;}/**** 获取TrackerServer*/private static TrackerServer getTrackerServer() throws IOException {TrackerClient trackerClient = new TrackerClient();TrackerServer trackerServer = trackerClient.getConnection();return trackerServer;}
}

使用 FastDFS 提供的客户端 storageClient 来进行文件上传,最后将上传结果返回。

根据 groupName 和文件名获取文件信息。

使用 FastDFS 时,直接调用 FastDFSClient 对应的方法即可。

4.4 编写上传控制类

从 MultipartFile 中读取文件信息,然后使用 FastDFSClient 将文件上传到 FastDFS 集群中。

package com.example.controller;import com.example.fastdfs.FastDFSClient;
import com.example.fastdfs.FastDFSFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;import java.io.IOException;
import java.io.InputStream;@Controller
public class UploadController {private static Logger logger = LoggerFactory.getLogger(UploadController.class);@GetMapping("/")public String index() {return "upload";}@PostMapping("/upload")public String singleFileUpload(@RequestParam("file") MultipartFile file,RedirectAttributes redirectAttributes) {if (file.isEmpty()) {redirectAttributes.addFlashAttribute("message", "Please select a file to upload");return "redirect:uploadStatus";}try {String path = saveFile(file);redirectAttributes.addFlashAttribute("message","You successfully uploaded '" + file.getOriginalFilename() + "'");redirectAttributes.addFlashAttribute("path","file path url '" + path + "'");} catch (Exception e) {logger.error("upload file failed", e);}return "redirect:/uploadStatus";}@GetMapping("/uploadStatus")public String uploadStatus() {return "uploadStatus";}/*** @param multipartFile* @return* @throws IOException*/public String saveFile(MultipartFile multipartFile) throws IOException {String[] fileAbsolutePath = {};String fileName = multipartFile.getOriginalFilename();String ext = fileName.substring(fileName.lastIndexOf(".") + 1);byte[] file_buff = null;InputStream inputStream = multipartFile.getInputStream();if (inputStream != null) {int len1 = inputStream.available();file_buff = new byte[len1];inputStream.read(file_buff);}inputStream.close();FastDFSFile file = new FastDFSFile(fileName, file_buff, ext);try {fileAbsolutePath = FastDFSClient.upload(file);  //upload to fastdfs} catch (Exception e) {logger.error("upload file Exception!", e);}if (fileAbsolutePath == null) {logger.error("upload file failed,please upload again!");}String path = FastDFSClient.getTrackerUrl() + fileAbsolutePath[0] + "/" + fileAbsolutePath[1];return path;}
}

请求控制,调用上面方法saveFile()

package com.example.controller;import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;@ControllerAdvice
public class GlobalExceptionHandler {//https://jira.spring.io/browse/SPR-14651//4.3.5 supports RedirectAttributes redirectAttributes@ExceptionHandler(MultipartException.class)public String handleError1(MultipartException e, RedirectAttributes redirectAttributes) {redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());return "redirect:/uploadStatus";}
}

4.5 上传页面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body><h1>Spring Boot file upload example</h1><form method="POST" action="/upload" enctype="multipart/form-data"><input type="file" name="file" /><br/><br/><input type="submit" value="Submit" />
</form></body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body><h1>Spring Boot - Upload Status</h1><div th:if="${message}"><h2 th:text="${message}"/>
</div><div th:if="${path}"><h2 th:text="${path}"/>
</div></body>
</html>

4.6 启动类

package com.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

上传成功之后,将文件的路径展示到页面,效果图如下:

在这里插入图片描述

在浏览器中访问此Url,可以看到成功通过FastDFS展示:

在这里插入图片描述

4.7 测试类

package com.example;import org.csource.fastdfs.*;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.InetSocketAddress;/*** @author zhangshixing*/
public class FastdfsClientTest {/*** 文件上传** @throws Exception*/@Testpublic void upload() throws Exception {// 加载全局的配置文件String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();ClientGlobal.init(filePath);//创建TrackerClient客户端对象TrackerClient trackerClient = new TrackerClient();//通过TrackerClient对象获取TrackerServer信息TrackerServer trackerServer = trackerClient.getConnection();//获取StorageClient对象StorageClient storageClient = new StorageClient(trackerServer, null);//执行文件上传String[] jpgs = storageClient.upload_file("C:\\Users\\Administrator\\Pictures\\5b13cd6cN8e12d4aa.jpg", "jpg", null);for (String jpg : jpgs) {System.out.println(jpg);}}@Testpublic void delete() throws Exception {//加载全局的配置文件String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();ClientGlobal.init(filePath);//创建TrackerClient客户端对象TrackerClient trackerClient = new TrackerClient();//通过TrackerClient对象获取TrackerServer信息TrackerServer trackerServer = trackerClient.getConnection();//获取StorageClient对象StorageClient storageClient = new StorageClient(trackerServer, null);//执行文件上传int group1 = storageClient.delete_file("group1", "M00/00/00/wKjThF1VEiyAJ0xzAANdC6JX9KA522.jpg");System.out.println(group1);}@Testpublic void download() throws Exception {//加载全局的配置文件String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();ClientGlobal.init(filePath);//创建TrackerClient客户端对象TrackerClient trackerClient = new TrackerClient();//通过TrackerClient对象获取TrackerServer信息TrackerServer trackerServer = trackerClient.getConnection();//获取StorageClient对象StorageClient storageClient = new StorageClient(trackerServer, null);//执行文件上传byte[] bytes = storageClient.download_file("group1", "M00/00/00/wKjThF1VFfKAJRJDAANdC6JX9KA980.jpg");File file = new File("D:\\ceshi\\1234.jpg");FileOutputStream fileOutputStream = new FileOutputStream(file);BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);bufferedOutputStream.write(bytes);bufferedOutputStream.close();fileOutputStream.close();}//获取文件的信息数据@Testpublic void getFileInfo() throws Exception {//加载全局的配置文件String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();ClientGlobal.init(filePath);//创建TrackerClient客户端对象TrackerClient trackerClient = new TrackerClient();//通过TrackerClient对象获取TrackerServer信息TrackerServer trackerServer = trackerClient.getConnection();//获取StorageClient对象StorageClient storageClient = new StorageClient(trackerServer, null);//执行文件上传FileInfo group1 = storageClient.get_file_info("group1", "M00/00/00/wKjThF1VFfKAJRJDAANdC6JX9KA980.jpg");System.out.println(group1);}//获取组相关的信息@Testpublic void getGroupInfo() throws Exception {//加载全局的配置文件String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();ClientGlobal.init(filePath);//创建TrackerClient客户端对象TrackerClient trackerClient = new TrackerClient();//通过TrackerClient对象获取TrackerServer信息TrackerServer trackerServer = trackerClient.getConnection();StorageServer group1 = trackerClient.getStoreStorage(trackerServer, "group1");System.out.println(group1.getStorePathIndex());//组对应的服务器的地址  因为有可能有多个服务器.ServerInfo[] group1s = trackerClient.getFetchStorages(trackerServer, "group1", "M00/00/00/wKjThF1VFfKAJRJDAANdC6JX9KA980.jpg");for (ServerInfo serverInfo : group1s) {System.out.println(serverInfo.getIpAddr());System.out.println(serverInfo.getPort());}}@Testpublic void getTrackerInfo() throws Exception {//加载全局的配置文件String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();ClientGlobal.init(filePath);//创建TrackerClient客户端对象TrackerClient trackerClient = new TrackerClient();//通过TrackerClient对象获取TrackerServer信息TrackerServer trackerServer = trackerClient.getConnection();InetSocketAddress inetSocketAddress = trackerServer.getInetSocketAddress();System.out.println(inetSocketAddress);}}

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

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

相关文章

vue2-006——使用脚手架搭建vue2项目+项目结构分析

一、创建项目&#xff1a;vue create 项目名 D:\EnyiWang\Documents\myStudy\vue>vue create vue_testVue CLI v5.0.8 ? Please pick a preset: Default ([Vue 2] babel, eslint)Vue CLI v5.0.8 ✨ Creating project in D:\EnyiWang\Documents\myStudy\vue\vue_test. &am…

设计测试用例的具体方法总结

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️白马沉河共歃誓&#xff0c;怒涛没城亦不悔 ☁️基于需求进行测试用例的设计 基…

[环境配置]vscode免密ssh的设置流程

测试环境&#xff1a; windows 11 ubuntu16.04 vmware 第一步&#xff1a;生成密钥 cmd打开输入&#xff1a;ssh-keygen -t rsa 一路回车后可以在C:\Users\用户名\.ssh路径看到id_rsa.pub&#xff0c;我们打开这个文件&#xff0c;用记事本打开即可&#xff0c;然后复制里…

“不得了·放飞杯” 2023年四川省健身健美锦标赛启动在成都隆重召开

“不得了放飞杯” 2023年四川省健身健美锦标赛启动在成都隆重召开 为了更好地推动四川省健身健美运动的普及和发展&#xff0c;结合《四川全民健身实施计划》的现状&#xff0c;适应新时代健身私教服务产业的发展需求&#xff0c;由中国健美协会指导&#xff0c;四川省健美健美…

BUUCTF [MRCTF2020]Ez_bypass 1

题目环境&#xff1a;F12查看源代码 I put something in F12 for you include flag.php; $flagMRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}; if(isset($_GET[gg])&&isset($_GET[id])) { $id$_GET[id]; $gg$_GET[gg]; if (md5($id) md5($gg) && $id ! $gg) { …

鸿蒙 ark ui 网络请求 我不允许你不会

前言&#xff1a; 最近有在学习这个鸿蒙的ark ui开发 因为鸿蒙不是发布了一个鸿蒙next的测试版本 明年会启动纯血鸿蒙应用 所以我就想提前给大家写一些博客文章 效果图 11-24 16:26:22.005 25156-25156/com.example.httpsrequest E A0ff00/HTTPS: 请求状态 --> 200, %{pub…

串口虚拟化工具

串口虚拟工具(Configure Virtual Serial Port Driver v7.2) 可以虚拟化串口 串口成对添加&#xff0c;添加之后可以在设备管理器中查看 链接&#xff1a;https://pan.baidu.com/s/1WE9c28MEoSEY7fGhy4kjag 提取码&#xff1a;yahn DebugTool-v.16 作用&#xff1a;可以检验…

区块链技术将如何影响未来的数字营销?

你是否听腻了区块链和数字营销等流行语&#xff0c;却不明白它们对未来意味着什么&#xff1f;那么&#xff0c;准备好系好安全带吧&#xff0c;因为区块链技术将彻底改变我们对数字营销的看法。从建立消费者信任到提高透明度和效率&#xff0c;其可能性是无限的。 让我们来探…

加速 Selenium 测试执行最佳实践

Selenium测试自动化的主要目的是加快测试过程。在大多数情况下&#xff0c;使用 Selenium 的自动化测试比手动测试执行得特别好。在实际自动化测试实践中&#xff0c;我们有很多方式可以加速Selenium用例的执行。 我们可以选择使用不同类型的等待、不同类型的 Web 定位器、不同…

[Docker]十一.Docker Swarm集群raft算法,Docker Swarm Web管理工具

一.Docker Swarm集群raft算法讲解 Raft &#xff1a;一致性算法&#xff0c;在保证大多数管理节点存活的情况下&#xff0c;集群才能使用&#xff0c; 所以就要求如果集群的话&#xff0c; manager 节点必须 >3 台 &#xff0c;如果是两个台&#xff0c;其中一台宕机&#…

彩纸屋在线少儿编程源码/scratch在线编程系统/培训管理系统源码/在线培训系统源码PHP

源码简介&#xff1a; 彩纸屋在线少儿编程源码&#xff0c;它是scratch在线编程系统&#xff0c;作为培训管理系统源码/在线培训系统源码&#xff0c;采用PHP源码。 彩纸屋是全国首家提供scratch开源定制和少儿编程培训管理系统源代码的服务商&#xff0c;彩纸屋提供的scratc…

一条Update语句的执行过程是怎样的?

先看第一个问题&#xff0c;这里做个简单描述 &#xff0c;因为我们着重还是看Update MySQL执行一条Select语句是怎么运行的&#xff1f; 这个问题大家在面试的时候大家都背过类似的题&#xff0c;而且网上也有很多答案&#xff0c;这里分享一个大致流程介绍&#xff0c;关于…

工业级 S25HS01GTDPBHV030 NOR闪存,L9305EP汽车级驱动器IC,LMK03318RHSR时钟发生器,PLL(中文资料)

一、工业级 S25HS01GTDPBHV030 Semper™ NOR闪存 S25HS01GT SEMPER™ NOR Flash闪存系列是英飞凌高性能、安全而可靠的 NOR Flash解决方案。 它集成了适用于汽车、工业、通信等广泛应用的关键安全功能。 凭借 SEMPER™ NOR Flash闪存&#xff0c;英飞凌推出了业界首款符合 ASI…

多线程04 线程安全问题以及一些简单的解决策略

前言 首先我们引入多线程是为了解决多次创建进程和销毁进程带来的巨大开销,线程可以共享内存和硬盘资源等等,这里我们就会想,他们共享这些东西会不会涉及到一些安全问题呢?他们没有独立分配自己的资源是一定会有安全问题的,但是就目前在这个快节奏的社会来说,效率的提升是必然…

Python编程之魂之运算符的优先级教程

文章目录 前言优先级概述相同优先级结合性运算符优先级一览表运算符优先级重点说明结语关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资…

深度学习基于Python+TensorFlow+Django的水果识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介简介技术组合系统功能使用流程 二、功能三、系统四. 总结 一项目简介 # 深度学习基于PythonTensorFlowDjango的水果识别系统介绍 简介 该水果识别系统基于…

PaddleOCR学习笔记

Paddle 功能特性 PP-OCR系列模型列表 https://github.com/PaddlePaddle/PaddleOCR#%EF%B8%8F-pp-ocr%E7%B3%BB%E5%88%97%E6%A8%A1%E5%9E%8B%E5%88%97%E8%A1%A8%E6%9B%B4%E6%96%B0%E4%B8%AD PP-OCR系列模型列表&#xff08;V4&#xff0c;2023年8月1日更新&#xff09; 配置文…

【论文解读】Edit-DiffNeRF:使用2D-扩散模型编辑3D-NeRF

来源&#xff1a;投稿 作者&#xff1a;橡皮 编辑&#xff1a;学姐 论文链接&#xff1a;https://arxiv.org/abs/2306.09551 摘要 最近的研究表明&#xff0c;将预训练的扩散模型与神经辐射场&#xff08;NeRF&#xff09;相结合&#xff0c;是一种很有前途的文本到 3D 的生成…

使用bard分析视频内容

11月21日的bard update 更新了分析视频的功能&#xff0c;使用方法如下&#xff1a; 1、打开bard网站。https://bard.google.com/ 2、点击插件。 3、点击YouTube中的 research a topic 选项。 4、输入需要分析的内容&#xff1a; Please analyze how many technologies are in…

企业计算机中了locked勒索病毒怎么解锁,locked勒索病毒解密,数据恢复

科技的进步为企业的生产生活提供了极大便利&#xff0c;但随之而来的网络安全威胁也不断增加&#xff0c;近期云天数据恢复中心陆续接到很多企业的求助&#xff0c;企业的计算机服务器遭到了locked勒索病毒攻击&#xff0c;导致企业的所有业务无法正常开展&#xff0c;所有计算…