Java实现对象存储的4种方式(本地对象存储、MINIO、阿里云OSS、FastDFS)

news2024/11/16 3:22:28

文章目录

  • Java实现对象存储的3中方式
    • 1、概述
    • 2、本地对象存储
      • 2.1 配置本地文件相关信息
      • 2.2 通用映射配置 ResourcesConfig
      • 2.3 文件上传业务 LocalSysFileServiceImpl
      • 2.4 上传接口
      • 2.5 演示
    • 3、MINIO
      • 3.1 依赖
      • 3.2 配置
      • 3.3 配置连接信息
      • 3.4. MINIO文件上传业务
      • 3.5 文件上传下载接口
      • 3.6 演示
    • 4、阿里云OSS
      • 功能特性:
      • 使用流程:
      • 安全与合规:
      • 步骤1:添加依赖
      • 步骤2:配置OSS客户端
      • 步骤3:文件上传
      • 步骤4:文件下载
      • 注意事项
    • 5、FastDFS
      • 步骤1:引入依赖
      • 步骤2:初始化FastDFS客户端配置
      • 步骤3:文件上传
      • 步骤4:文件下载
      • 注意事项

Java实现对象存储的3中方式

1、概述

对象存储(Object Storage)是一种数据存储架构,它以对象(Object)为基本单位管理数据,区别于传统的文件存储(按目录层级组织)和块存储(主要用于磁盘和卷)。在对象存储中,每个对象包含数据本身、可变数量的元数据(描述数据的信息)和一个全局唯一的标识符(通常是对象的名称或键)。这种存储模型非常适合处理非结构化数据,如图片、视频、文档等。

对象存储的主要特点包括:

  1. 扁平化命名空间:对象存储没有文件系统的目录树结构,所有对象都存储在一个扁平的命名空间(通常称为“容器”或“桶”Bucket)中,通过对象的唯一标识符访问。
  2. 高度可扩展性:对象存储设计用于海量数据存储,能够容易地水平扩展存储容量,适应不断增长的数据需求。
  3. 元数据灵活性:每个对象可以携带丰富的元数据,使得数据管理和搜索更加灵活高效。
  4. 数据冗余与分布:为了确保数据的高可用性和持久性,对象存储通常会在多个地理位置复制数据,即使某个存储节点发生故障也不会丢失数据。
  5. 基于网络的访问:通过标准的网络协议(如HTTP/HTTPS)和RESTful API访问数据,便于跨平台和远程访问。
  6. 成本效益:由于其规模经济和优化的存储效率,对象存储通常比其他类型的存储更经济,特别是对于大量非频繁访问的数据(冷数据或温数据)。
  7. 安全性:对象存储提供多种安全措施,包括数据加密(静态和传输过程中的)、访问控制列表(ACL)、身份验证机制等,以保护数据免受未授权访问。

对象存储广泛应用于云存储服务、大数据分析、内容分发网络(CDN)、备份与归档、以及许多需要处理大量非结构化数据的应用场景中。

2、本地对象存储

2.1 配置本地文件相关信息

# 本地文件存储
file:
  # 本地存放的路径地址
  path: D:/develop/学习/spring-boot3/file
  # 映射地址
  prefix: /static
  # 访问地址
  domain: http://127.0.0.1:${server.port}

我们通过将文件上传到我们指定的本地存放的路径地址,通过访问地址+映射地址+文件名可以直接访问到本地的这个文件

2.2 通用映射配置 ResourcesConfig

@Configuration
public class ResourcesConfig implements WebMvcConfigurer
{
    /**
     * 上传文件存储在本地的根路径
     */
    @Value("${file.path}")
    private String localFilePath;

    /**
     * 资源映射路径 前缀
     */
    @Value("${file.prefix}")
    public String localFilePrefix;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry)
    {
        /** 本地文件上传路径 */
        registry.addResourceHandler(localFilePrefix + "/**")
                .addResourceLocations("file:" + localFilePath + File.separator);
    }
    
    /**
     * 开启跨域
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 设置允许跨域的路由
        registry.addMapping(localFilePrefix  + "/**")
                // 设置允许跨域请求的域名
                .allowedOrigins("*")
                // 设置允许的方法
                .allowedMethods("GET");
    }
}

2.3 文件上传业务 LocalSysFileServiceImpl

@Primary
@Service
@Slf4j
public class LocalSysFileServiceImpl implements ISysFileService {
    /**
     * 资源映射路径 前缀
     */
    @Value("${file.prefix}")
    public String localFilePrefix;

    /**
     * 域名或本机访问地址
     */
    @Value("${file.domain}")
    public String domain;

    /**
     * 上传文件存储在本地的根路径
     */
    @Value("${file.path}")
    private String localFilePath;

    @Value("${server.servlet.context-path}")
    private String path;


    /**
     * 本地文件上传接口
     *
     * @param file 上传的文件
     * @return 访问地址
     * @throws Exception
     */
    @Override
    public String uploadFile(MultipartFile file) {
        try {
            String name = FileUploadUtils.upload(localFilePath, file);
            return domain + path + localFilePrefix + name;
        } catch (Exception e) {
            log.info("上传文件失败", e);
            return "";
        }
    }
}

2.4 上传接口

@RestController
@Tag(name = "文件控制器")
@RequestMapping("file")
public class SysFileController {
    private static final Logger log = LoggerFactory.getLogger(SysFileController.class);

    @Autowired
    private ISysFileService sysFileService;

    /**
     * 本地文件上传请求
     */
    @Operation(summary = "本地文件上传请求")
    @PostMapping("/uploadStatic")
    public CommonResult upload(MultipartFile file) {
        return CommonResult.SUCCESS(sysFileService.uploadFile(file));
    }

}

2.5 演示

上传

在这里插入图片描述

访问
在这里插入图片描述

3、MINIO

3.1 依赖

        <!-- 分布式对象存储minio -->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>${minio.version}</version>
        </dependency>

3.2 配置

# MinIO 分布式文件系统
minio:
  url: http://127.0.0.1:9000
  # 账号
  accessKey: minioadmin
  # 密码
  secretKey: minioadmin
  # MinIO桶名字
  bucketName: youzi

3.3 配置连接信息

在代码中配置Access Key ID、Secret Access Key和Endpoint,以建立与对象存储服务的连接。

@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {

    /**
     * 服务地址
     */
    private String url;

    /**
     * 用户名
     */
    private String accessKey;

    /**
     * 密码
     */
    private String secretKey;

    /**
     * 存储桶名称
     */
    private String bucketName;

    @Bean
    public MinioClient getMinioClient()
    {
        return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
    }

}

3.4. MINIO文件上传业务

我这里使用一个接口对应多个不同实现类的设计模式典型地体现了**策略模式(Strategy Pattern)**的思想。策略模式定义了一系列算法,并将每一个算法封装起来,使它们可以相互替换,让算法的变化独立于使用算法的客户。在这种模式中,一个接口(策略接口)定义了多种行为或算法,而每种行为或算法都有一个具体的实现类。客户端可以通过使用不同的实现类来改变程序的行为,而不需要了解这些类是如何实现的。

在这里插入图片描述

/**
 * Minio 文件存储
 *
 * @author ruoyi
 */
@Service
@Slf4j
public class MinioSysFileServiceImpl implements ISysFileService
{

    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioClient client;



    /**
     * Minio文件上传接口
     *
     * @param file 上传的文件
     * @return 访问地址
     * @throws Exception
     */
    @Override
    public String uploadFile(MultipartFile file){

        try {
            String path = "test/";
            String fileName = path + FileUploadUtils.extractFilename(file);
            InputStream inputStream = file.getInputStream();
            PutObjectArgs args = PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build();
            client.putObject(args);
            inputStream.close();
            return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
        } catch (Exception e) {
            log.info("上传文件失败", e);
            return "";
        }
    }

    @Override
    public void downloaFile(String fileName, HttpServletResponse response) {
        try {
            GetObjectArgs object = GetObjectArgs.builder().bucket(minioConfig.getBucketName()).object(fileName).build();
            InputStream stream = client.getObject(object);
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");
            // 设置文件名
            String downloadName = fileName.substring(fileName.lastIndexOf("/") + 1);
            response.setHeader("Content-Disposition", "attachment;filename=" + downloadName);
            OutputStream outputStream = response.getOutputStream();
            byte[] buf = new byte[1024];
            int bytesRead;
            while ((bytesRead = stream.read(buf)) != -1) {
                outputStream.write(buf, 0, bytesRead);
            }
            outputStream.flush();
            stream.close();
            outputStream.close();
            log.info("《==病历Excel文件下载成功,MINIO文件名:{}==》", fileName);
        } catch (Exception e) {
            System.err.println("Error streaming file: " + e.getMessage());
        }
    }
}

3.5 文件上传下载接口

@RestController
@Tag(name = "文件控制器")
@RequestMapping("file")
public class SysFileController {
    private static final Logger log = LoggerFactory.getLogger(SysFileController.class);

    @Autowired
    private ISysFileService sysFileService;

    @Autowired
    @Qualifier("minioSysFileServiceImpl")
    private ISysFileService minioSysFileServiceImpl;

    /**
     * MinIo文件上传请求
     */
    @Operation(summary = "MinIo文件上传请求")
    @PostMapping("/uploadMinIo")
    public CommonResult uploadMinIo(MultipartFile file) {
        return CommonResult.SUCCESS(minioSysFileServiceImpl.uploadFile(file));
    }

    /**
     * MinIo文件上传请求
     */
    @Operation(summary = "MinIo文件下载")
    @PostMapping("/downloadMinIo")
    public void downloadMinIo(String fileName, HttpServletResponse response) {
        minioSysFileServiceImpl.downloaFile(fileName,response);
    }
}

3.6 演示

上传

在这里插入图片描述

访问
在这里插入图片描述

下载
在这里插入图片描述

4、阿里云OSS

阿里云OSS(Object Storage Service)是阿里巴巴云提供的一种海量、安全、低成本、高可靠的云存储服务。OSS专为互联网和移动应用设计,特别适合存储图片、音视频、文档、网站内容等多种类型的数据。以下是使用阿里云OSS的一些关键点和流程:

功能特性:

  1. 海量存储:支持存储数十亿级别的文件,容量近乎无限扩展。
  2. 高可靠性:数据多重冗余备份,99.999999999%(11个9)的数据持久性。
  3. 高速访问:全球CDN加速,提供低延迟、大带宽的数据访问能力。
  4. 安全性:支持HTTPS、防盗链、STS临时授权、RAM访问控制等安全措施。
  5. 成本效益:按实际使用量计费,无最低消费限制,且长期存储费用较低。
  6. 灵活的API访问:提供基于HTTP/HTTPS的RESTful API接口,支持多语言SDK(包括Java、Python、PHP、Node.js等)。

使用流程:

  1. 注册与实名认证:首先在阿里云官网注册账号并完成实名认证。

  2. 购买与开通OSS服务:在阿里云控制台购买OSS服务并开通。

  3. 创建Bucket:登录OSS控制台,创建一个或多个存储空间(Bucket),用于存储对象。

  4. 上传文件

    :通过控制台或者使用SDK编写代码,将文件上传至指定的Bucket中。

    • 可以直接上传文件,或使用分片上传处理大文件。
  5. 管理文件:在控制台上查看、下载、删除文件,或设置访问权限、生命周期规则等。

  6. 下载与分发:通过URL直接访问或使用CDN加速访问存储在OSS中的文件。

  7. API与SDK集成:在应用中集成OSS SDK,实现自动化文件管理,如在上传、下载、删除等操作中动态调用API。

安全与合规:

  • 设置合适的访问权限,如公有读私有写、私有读写等。
  • 使用RAM(Resource Access Management)进行细粒度的权限控制。
  • 开启日志审计,监控和追踪OSS资源访问情况。

步骤1:添加依赖

确保你的项目中已经包含了阿里云OSS SDK的依赖。如果你使用的是Maven,可以在pom.xml中添加如下依赖:

Xml

<dependency>
    <groupId>com.aliyun.oss</groupId>
   <artifactId>aliyun-sdk-oss</artifactId>
<!-- 请替换为最新的版本号 -->
    <version>3.10.2</version>
</dependency>

步骤2:配置OSS客户端

在代码中配置OSS客户端,包括Endpoint、AccessKeyId、AccessKeySecret以及Bucket名称。

Java

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;

public class OssDemo {
    public static void main(String[] args) {
        String endpoint = "<你的Endpoint>";
        String accessKeyId = "<你的AccessKeyId>";
        String accessKeySecret = "<你的AccessKeySecret>";
        String bucketName = "<你的Bucket名称>";

        // 创建OSSClient实例
       OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        // 进行上传和下载操作...

        // 关闭OSSClient
        ossClient.shutdown();
    }
}

步骤3:文件上传

使用putObject方法上传文件到OSS。

Java

// 上传文件
String uploadFilePath = "<本地文件路径>";
String objectName = "<OSS中的对象键,即上传后的文件名>";
ossClient.putObject(bucketName, objectName, new File(uploadFilePath));
System.out.println("文件上传成功");

步骤4:文件下载

使用getObject方法从OSS下载文件到本地。

Java

// 下载文件
String downloadFilePath = "<本地保存路径>";
String downloadObjectName = "<OSS中的对象键,即要下载的文件名>";
ossClient.getObject(new GetObjectRequest(bucketName, downloadObjectName), new File(downloadFilePath));
System.out.println("文件下载成功");

注意事项

  • 请确保替换上述代码中的<你的Endpoint><你的AccessKeyId><你的AccessKeySecret><你的Bucket名称><本地文件路径><OSS中的对象键>等占位符为实际的值。
  • 在生产环境中,建议使用STS(Security Token Service)临时凭证来增强安全性,避免直接使用AccessKey和SecretKey。
  • 操作完成后记得关闭OSSClient,以释放资源。

以上就是Java程序中使用阿里云OSS实现文件上传和下载的基本步骤。

5、FastDFS

FastDFS,这是一个开源的高性能分布式文件系统,而非FSTFastDfs。在Java程序中使用FastDFS进行文件的上传和下载,通常需要依赖FastDFS的Java客户端库,比如fastdfs-client-java

步骤1:引入依赖

如果是Maven项目,你需要在pom.xml中添加FastDFS客户端的依赖:

Xml

<dependency>
    <groupId>org.csource.fastdfs</groupId>
    <artifactId>fastdfs-client-java</artifactId>
    <!-- 请根据实际情况填写正确的版本号 -->
    <version>最新版本号</version>
</dependency>

步骤2:初始化FastDFS客户端配置

在使用FastDFS客户端之前,需要对其进行初始化,通常通过加载配置文件来完成。配置文件中包含Tracker服务器的地址等信息。

Java

import org.csource.fastdfs.*;

public class FastDFSClientExample {
    static {
       try {
            ClientGlobal.init("classpath:fastdfs-client.properties");
        } catch (IOException e) {
           e.printStackTrace();
            throw new RuntimeException("FastDFS Client Init Fail!", e);
        }
    }
    // ... 其他代码
}

步骤3:文件上传

使用TrackerClientStorageClient来上传文件。

Java

public String uploadFile(String filePath) {
    try {
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();
        StorageClient storageClient = new StorageClient(trackerServer, null);

        // 上传文件,并获取文件的存储信息(组名和文件路径)
       String[] uploadResults = storageClient.upload_file(filePath, "jpg", null);
       if (uploadResults != null && uploadResults.length == 2) {
            return uploadResults[0] + "/" + uploadResults[1];
        } else {
            throw new RuntimeException("文件上传失败!");
        }
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException("文件上传异常!", e);
    }
}

步骤4:文件下载

下载文件需要根据文件的存储信息(组名和文件路径)来进行。

Java

public void downloadFile(String groupName, String remoteFileName, String localFilePath) {
    try {
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();
        StorageClient storageClient = new StorageClient(trackerServer, null);

        // 下载文件到本地
        byte[] fileBytes = storageClient.download_file(groupName, remoteFileName);
        if (fileBytes != null) {
            FileOutputStream out = new FileOutputStream(localFilePath);
           out.write(fileBytes);
            out.flush();
           out.close();
            System.out.println("文件下载成功");
        } else {
           throw new RuntimeException("文件下载失败!");
        }
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException("文件下载异常!", e);
    }
}

注意事项

  • 确保fastdfs-client.properties配置文件正确配置了Tracker服务器地址。
  • 上传和下载的文件名(特别是远程文件名)应遵循FastDFS的规定,有时需要指定文件扩展名以供FastDFS进行正确的MIME类型识别。
  • 在实际应用中,应当适当处理异常,并考虑资源的释放和错误的重试逻辑。

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

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

相关文章

高考前很焦虑?看看罗永浩提的三个建议!罗永浩推荐的随身WiFi居然蕴含这样的商机?2024普通人如何翻身?

你能相信现如今身家过亿的老罗罗永浩高中就辍学了吗&#xff1f;相信很多人都不敢置信吧。罗永浩无论是表现出来的口才、情商还是智商&#xff0c;无论如何都无法让人把他和高中辍学联系起来。 而这一点似乎也是老罗人生中的一个遗憾&#xff0c;于是又在一年高考季的时候&…

【AREngine BUG 解决方法】无法获取有效的相机图像尺寸

近期拿了一台 华为mate20 Pro的手机&#xff0c;在运行AR示例的过程中出现了黑屏。 问题排查 SDK版本&#xff1a;com.huawei.hms:arenginesdk:3.7.0.3 定位 经排查&#xff0c;发现(ARCamera对象的相机内参) getImageDimensions()返回的图像尺寸的width和height都为0。 这…

【AI大模型】如何让大模型变得更聪明?基于时代背景的思考

【AI大模型】如何让大模型变得更聪明 前言 在以前&#xff0c;AI和大模型实际上界限较为清晰。但是随着人工智能技术的不断发展&#xff0c;基于大规模预训练模型的应用在基于AI人工智能的技术支持和帮助上&#xff0c;多个领域展现出了前所未有的能力。无论是自然语言处理、…

Dinky MySQLCDC 整库同步到 Doris

资源&#xff1a;flink 1.17.0、dinky 1.0.2、doris-2.0.1-rc04 问题&#xff1a;Cannot deserialize value of type int from String &#xff0c;detailMessageunknowndatabases &#xff0c;not a valid int value 2024-05-29 16:52:20.136 ERROR org.apache.doris.flink.…

电脑录屏怎么录?7个电脑录屏软件免费版强势来袭,赶快收藏!

电脑录屏怎么录&#xff1f;相信很多小伙伴们都不知道怎么在Windows电脑上录屏吧&#xff1f;在当今社会&#xff0c;随着互联网的快速发展&#xff0c;越来越多的小伙伴们开始通过制作视频内容来分享知识、展示技能或者记录生活。电脑录屏成为了一种简单高效的方式&#xff0c…

C语言-----指针数组 \ 数组指针

一 指针数组 用来存放指针的数组 int arr[10]; //整型数组 char ch[5]; //字符数组 int * arr[6]; //存放整型指针的数组 char * arr[5]; //存放字符指针的数组 // 指针数组的应用 int main() {int arr1[] { 1,2,3,4,5 };int arr2[] { 2,3,4,5,6 };int arr3[] { 3,4,…

LED显示屏模组七大参数

LED模组是LED显示屏的核心组件&#xff0c;它包含LED线路板和外壳&#xff0c;将LED灯珠按照特定规则排列并封装&#xff0c;通常还会进行防水处理。随着LED显示屏行业的发展及其广泛应用&#xff0c;LED模组的功能和作用变得愈加重要。那么&#xff0c;LED模组的七大参数是什么…

光栅幅值细分原理与实现

本文介绍光栅幅值细分原理与实现。 光栅是工业测量领域中常见的传感器&#xff0c;如下图。主要厂家有雷尼绍&#xff0c;海德汉&#xff0c;配套的光栅读数头有模拟信号的&#xff0c;也有直接细分输出数字脉冲的&#xff0c;本文的细分针对模拟信号&#xff0c;即有正弦信号…

苹果iOS18将引入ChatGPT;美国AI禁令再升级;微软首发Phi-3多模态模型 | AI头条

整理 | 王轶群 出品 | AI 科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09; 一分钟速览新闻点&#xff01; 谷歌努力手动删除搜索中奇怪的人工智能答案 苹果和OpenAI签订协议&#xff0c;将在iOS18引入ChatGPT 微软发布主打视觉能力的 Phi-3-vision 模型 苹果押注…

SOLIDWORKS正版价格多少钱

SOLIDWORKS作为目前应用较为广泛的3D CAD软件之一&#xff0c;具有强大的功能和实用性&#xff0c;它为各类工程设计提供综合解决方案。但是&#xff0c;正版SOLIDWORKS价格是个不可忽视的问题。那SOLIDWORKS的正版价格究竟如何呢&#xff1f;又是受什么因素影响&#xff1f; 先…

SpringBoot 之基础(一)

文章目录 SpringBoot 基础基本概念创建 SpringBoot 项目编码编写启动类写 Controller运行 / 测试properties 和 yml关闭 Spring banner日志spring-boot 默认的日志格式 解决 start.spring.io 不能访问不使用 spring boot 的 parent pom SpringBoot 基础 Spring Boot 是由 Pivo…

【SpringMVC】_SpringMVC项目返回HTML与JSON

目录 1. SpringMVC项目返回HTML页面 2. SpringMVC项目返回JSON 2.1 程序演示 2.2 关于响应的Content-Type 2.2.1 接口为对象 2.2.2 接口为String 2.2.3 接口为Map 本专栏已介绍&#xff1a; 返回静态页面&#xff1a; 【Spring MVC】_SpringMVC项目返回静态页面_mvc 返…

C# 数组/集合排序

一&#xff1a;基础类型集合排序 /// <summary> /// 排序 /// </summary> /// <param name"isReverse">顺序是否取反</param> public static void Sort<T>(this IList<T> array, bool isReverse false)where T : IComparable …

Linux下多线程的相关概念

&#x1f916;个人主页&#xff1a;晚风相伴-CSDN博客 &#x1f496;如果觉得内容对你有帮助的话&#xff0c;还请给博主一键三连&#xff08;点赞&#x1f49c;、收藏&#x1f9e1;、关注&#x1f49a;&#xff09;吧 &#x1f64f;如果内容有误或者有写的不好的地方的话&…

py黑帽子学习笔记_scapy

简介 代码简洁&#xff1a;相比于前两个博客总结&#xff0c;很多socket操作&#xff0c;如果使用scapy仅需几行代码即可实现 获取邮箱身份凭证 编写基础嗅探器&#xff0c;脚本可显示任何收到的一个包的详细情况 直接运行 尝试监听邮件收发&#xff0c;监听指定端口&#x…

2024年03月 Python(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 以下选项中,创建类正确的是?() A: class test1: def prt(self): …… B: class Mg(): def__init__(na,ag): self.na=na C: class A(): def print(self): print(“Yes”) a=A() a.print() D…

理解多线程看这一篇就够了

一、基本概念与关系 程序 程序是含有指令和数据的文件&#xff0c;静态地存储在磁盘等存储设备上。它是软件的实体&#xff0c;但未被激活。 进程 进程是程序的一次执行过程&#xff0c;是系统运行程序的基本单位。当程序被操作系统加载并执行时&#xff0c;就成为一个进程&a…

Kprobe实现原理

kprobe其实就是将某个要检测的指令备份&#xff0c;再替换成int3(x86)或者未定义指令(arm)来触发异常&#xff0c;再调用对应体系的异常处理函数来执行我们自定义的hook&#xff0c;执行完我们自定义的hook,再将备份的指令放回原来的位置继续往下执行 下面我们就来看下linux内核…

拍视频麦克风什么牌子好?户外无线麦克风哪个牌子好,看本期文章

​无线领夹麦克风&#xff0c;作为现代音频技术的重要代表&#xff0c;已经广泛应用于各种场合。它不仅能提高演讲者的声音质量&#xff0c;还能增加演讲的互动性和生动性。然而&#xff0c;面对市场上众多的无线领夹麦克风产品&#xff0c;如何选择一款适合自己的设备成为了一…

TPshop商城的保姆教程(windows)

提前准备 phpStudy下载&#xff1a;https://www.xp.cn/download.html 选择适合自己的版本下载 TPshop商城源文件下载链接&#xff1a; https://pan.baidu.com/s/143fLrxbwe9CTMCbyx7mXJQ?pwd6666 开始安装 安装完phpstudy后 以管理员的身份启动phpstudy.exe 选择合适自己…