OSS上传(Java和Js)

news2025/2/28 1:33:37

OSS上传(Java和Js)

  • 准备工作
    • 创建RAM用户
    • 创建角色
    • 创建权限策略
    • 给角色授予权限策略
  • 获取临时访问凭证
  • Java普通上传OSS
  • Java分片上传OSS
  • JS普通上传OSS
  • JS分片上传OSS

使用RAM用户或STS方式访问
由于阿里云账号AccessKey拥有所有API访问权限,建议遵循阿里云安全最佳实践。如果部署在服务端可以使用RAM用户或STS来进行API访问或日常运维管控操作,如果部署在客户端请使用STS方式来进行API访问。

本文采用STS方式来实现上传功能,STS可以给第三方提供权限,在考虑接口安全的前提下,还是很合适的,当然如果是自己企业使用的话,也可以直接用RAM用户方式。代码都是类似的

准备工作

登录控制台进入RAM控制台
在这里插入图片描述

创建RAM用户

在这里插入图片描述

在这里插入图片描述
创建完成之后记得复制密钥后面代码里面要用到
在这里插入图片描述
返回用户列表,点击添加权限,现在下面权限后点击确定

在这里插入图片描述

创建角色

在这里插入图片描述
选择阿里云账号,点击下一步
在这里插入图片描述
输入名称,点击下一步
在这里插入图片描述
点击完成创建
在这里插入图片描述

然后角色列表,找到刚刚创建的角色,点击进入
在这里插入图片描述
复制角色的ARN,后面的代码里面会用到
在这里插入图片描述

创建权限策略

在这里插入图片描述

输入脚本
PutObject就是用form表单的方式上传,resource就是bucket资源路径,这个自行修改

{
    "Version": "1",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "oss:PutObject",
            "Resource": [
                "acs:oss:*:*:test/img/*",
                "acs:oss:*:*:test/mp4/*"
            ]
        }
    ]
}

在这里插入图片描述
然后点击继续编辑,添加名称后点击 确定即可

在这里插入图片描述

给角色授予权限策略

进入角色列表找到刚刚新建的角色,点击添加权限
在这里插入图片描述
选择刚刚创建的权限策略,点击确定

在这里插入图片描述

获取临时访问凭证

<!--阿里云oss-->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>

注意替换你自己的id 和 secret,这个生成的token有效期默认是3600秒,可以根据业务场景自己调整

public static void main(String[] args) {
    // STS接入地址,例如sts.cn-hangzhou.aliyuncs.com。
    String endpoint = "sts.cn-hangzhou.aliyuncs.com";
    // 填写步骤1生成的RAM用户访问密钥AccessKey ID和AccessKey Secret。
    String accessKeyId = "你刚刚创建的RAM用户的AccessKey ID";
    String accessKeySecret = "你刚刚创建的RAM用户的AccessKey Secret";
    // 填写步骤3获取的角色ARN。
    String roleArn = "你刚刚创建的RAM用户的ARN";
    // 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。
    String roleSessionName = "SessionTest";
    // 以下Policy用于限制仅允许使用临时访问凭证向目标存储空间examplebucket上传文件。
    // 临时访问凭证最后获得的权限是步骤4设置的角色权限和该Policy设置权限的交集,即仅允许将文件上传至目标存储空间examplebucket下的exampledir目录。
    // 如果policy为空,则用户将获得该角色下所有权限。
    String policy = "{\n" +
            "    \"Version\": \"1\", \n" +
            "    \"Statement\": [\n" +
            "        {\n" +
            "            \"Action\": [\n" +
            "                \"oss:PutObject\"\n" +
            "            ], \n" +
            "            \"Resource\": [\n" +
            "                \"acs:oss:*:*:test/*\" \n" +
            "            ], \n" +
            "            \"Effect\": \"Allow\"\n" +
            "        }\n" +
            "    ]\n" +
            "}";
    // 设置临时访问凭证的有效时间为3600秒。
    Long durationSeconds = 3600L;
    try {
        // regionId表示RAM的地域ID。以华东1(杭州)地域为例,regionID填写为cn-hangzhou。也可以保留默认值,默认值为空字符串("")。
        String regionId = "";
        // 添加endpoint。适用于Java SDK 3.12.0及以上版本。
        //DefaultProfile.addEndpoint(regionId, "Sts", endpoint);
        // 添加endpoint。适用于Java SDK 3.12.0以下版本。
        DefaultProfile.addEndpoint("",regionId, "Sts", endpoint);
        // 构造default profile。
        IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        // 构造client。
        DefaultAcsClient client = new DefaultAcsClient(profile);
        final AssumeRoleRequest request = new AssumeRoleRequest();
        // 适用于Java SDK 3.12.0及以上版本。
        //request.setSysMethod(MethodType.POST);
        // 适用于Java SDK 3.12.0以下版本。
        request.setMethod(MethodType.POST);
        request.setRoleArn(roleArn);
        request.setRoleSessionName(roleSessionName);
        request.setPolicy(policy);
        request.setDurationSeconds(durationSeconds);
        final AssumeRoleResponse response = client.getAcsResponse(request);
        System.out.println("Expiration: " + response.getCredentials().getExpiration());
        System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
        System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
        System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
        System.out.println("RequestId: " + response.getRequestId());
    } catch (ClientException e) {
        System.out.println("Failed:");
        System.out.println("Error code: " + e.getErrCode());
        System.out.println("Error message: " + e.getErrMsg());
        System.out.println("RequestId: " + e.getRequestId());
    }
}

运行main方法,控制台输出
下面上传代码里用到的id secret token都是用这里生成的,而不是RAM用户的,千万别搞错了

在这里插入图片描述

Java普通上传OSS

public static void main(String[] args) {
    SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date1 = new Date();
    System.out.println("上传开始---" + dateFormat.format(date1));

    // Endpoint以杭州为例,其它Region请按实际情况填写。
    String endpoint = "oss-cn-hangzhou.aliyuncs.com";
    // 填写步骤五获取的临时访问密钥AccessKey ID和AccessKey Secret,非阿里云账号AccessKey ID和AccessKey Secret。
    String accessKeyId = "上一步获取的id";
    String accessKeySecret = "上一步获取的secret";
    // 填写步骤五获取的安全令牌SecurityToken。
    String securityToken = "上一步获取的token";

    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
    // 将本地文件exampletest.txt上传至目标存储空间examplebucket下的目录exampledir。
    PutObjectRequest putObjectRequest = new PutObjectRequest("test", "mp4/111.mp4", new File("D:\\test\\111.mp4"));

    // ObjectMetadata metadata = new ObjectMetadata();
    // 上传文件时设置存储类型。
    // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
    // 上传文件时设置读写权限ACL。
    // metadata.setObjectAcl(CannedAccessControlList.Private);
    // putObjectRequest.setMetadata(metadata);

    // 上传文件。
    ossClient.putObject(putObjectRequest);

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

    Date date2 = new Date();
    System.out.println("上传结束---" + dateFormat.format(date2));
}

运行mian方法成功,去控制台查看是否上传成功,如果没有看到上传的文件,看看是不是路径写错了,或者token过期了,

Java分片上传OSS

分片只有在大文件才能发挥出他的功效,例如1G的文件,如果是几百兆的文件是看不出效果的,有分片上传比普通上传还要慢一些

public static void main(String[] args) throws Exception {

    SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date1 = new Date();
    System.out.println("上传开始---" + dateFormat.format(date1));
    // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
    String endpoint = "oss-cn-hangzhou.aliyuncs.com";
    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    String accessKeyId = "刚刚获取的id";
    String accessKeySecret = "刚刚获取的secret";
    String securityToken = "刚刚获取的token";
    // 填写Bucket名称,例如examplebucket。
    String bucketName = "test";
    // 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
    String objectName = "mp4/111.mp4";

    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret,securityToken);
    try {
        // 创建InitiateMultipartUploadRequest对象。
        InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);

        // 初始化分片。
        InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
        // 返回uploadId,它是分片上传事件的唯一标识。您可以根据该uploadId发起相关的操作,例如取消分片上传、查询分片上传等。
        String uploadId = upresult.getUploadId();

        // partETags是PartETag的集合。PartETag由分片的ETag和分片号组成。
        List<PartETag> partETags =  new ArrayList<PartETag>();
        // 每个分片的大小,用于计算文件有多少个分片。单位为字节。
        final long partSize = 1 * 1024 * 1024L;   //1 MB。

        // 填写本地文件的完整路径。
        final File sampleFile = new File("D:\\test\\111.mp4");
        long fileLength = sampleFile.length();
        int partCount = (int) (fileLength / partSize);
        if (fileLength % partSize != 0) {
            partCount++;
        }
        // 遍历分片上传。
        for (int i = 0; i < partCount; i++) {
            long startPos = i * partSize;
            long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
            InputStream instream = new FileInputStream(sampleFile);
            // 跳过已经上传的分片。
            instream.skip(startPos);
            UploadPartRequest uploadPartRequest = new UploadPartRequest();
            uploadPartRequest.setBucketName(bucketName);
            uploadPartRequest.setKey(objectName);
            uploadPartRequest.setUploadId(uploadId);
            uploadPartRequest.setInputStream(instream);
            // 设置分片大小。除了最后一个分片没有大小限制,其他的分片最小为100 KB。
            uploadPartRequest.setPartSize(curPartSize);
            // 设置分片号。每一个上传的分片都有一个分片号,取值范围是1~10000,如果超出此范围,OSS将返回InvalidArgument错误码。
            uploadPartRequest.setPartNumber( i + 1);
            // 每个分片不需要按顺序上传,甚至可以在不同客户端上传,OSS会按照分片号排序组成完整的文件。
            UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
            // 每次上传分片之后,OSS的返回结果包含PartETag。PartETag将被保存在partETags中。
            partETags.add(uploadPartResult.getPartETag());
        }

        // 创建CompleteMultipartUploadRequest对象。
        // 在执行完成分片上传操作时,需要提供所有有效的partETags。OSS收到提交的partETags后,会逐一验证每个分片的有效性。当所有的数据分片验证通过后,OSS将把这些分片组合成一个完整的文件。
        CompleteMultipartUploadRequest completeMultipartUploadRequest =
                new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
        System.out.println("分片---" + partETags.size());
        // 完成分片上传。
        CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
        System.out.println(completeMultipartUploadResult.getETag());
    } catch (OSSException oe) {
        System.out.println("Caught an OSSException, which means your request made it to OSS, "
                + "but was rejected with an error response for some reason.");
        System.out.println("Error Message:" + oe.getErrorMessage());
        System.out.println("Error Code:" + oe.getErrorCode());
        System.out.println("Request ID:" + oe.getRequestId());
        System.out.println("Host ID:" + oe.getHostId());
    } catch (ClientException ce) {
        System.out.println("Caught an ClientException, which means the client encountered "
                + "a serious internal problem while trying to communicate with OSS, "
                + "such as not being able to access the network.");
        System.out.println("Error Message:" + ce.getMessage());
    } finally {
        if (ossClient != null) {
            ossClient.shutdown();
            Date date2 = new Date();
            System.out.println("上传结束---" + dateFormat.format(date2));

        }
    }
}

JS普通上传OSS

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>

  <body>
    <button id="upload">上传</button>
    <input id="file" type="file" />
    <!--导入SDK文件-->
    <script
      type="text/javascript"
      src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"
    ></script>
    <script type="text/javascript">
      const client = new OSS({
        // yourRegion填写Bucket所在地域。以华东1(杭州)为例,yourRegion填写为oss-cn-hangzhou。
        region: 'oss-cn-hangzhou',
        // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
        accessKeyId: '刚刚获取的id',
        accessKeySecret: '刚刚获取的secret',
        // 从STS服务获取的安全令牌(SecurityToken)。
        stsToken: '刚刚获取的token',
        // 填写Bucket名称。
        bucket: 'test'
      });

      // 从输入框获取file对象,例如<input type="file" id="file" />。
      let data;
      // 创建并填写Blob数据。
      //const data = new Blob(['Hello OSS']);
      // 创建并填写OSS Buffer内容。
      //const data = new OSS.Buffer(['Hello OSS']);

      const upload = document.getElementById("upload");

      const headers = {};

       async function putObject (data) {
         try {
           // 填写Object完整路径。Object完整路径中不能包含Bucket名称。
           // 您可以通过自定义文件名(例如exampleobject.txt)或文件完整路径(例如exampledir/exampleobject.txt)的形式实现将数据上传到当前Bucket或Bucket中的指定目录。
           // data对象可以自定义为file对象、Blob数据或者OSS Buffer。
          const result = await client.put(
            "mp4/111.mp4",
            data
            //{headers}
          );
          console.log(result);
        } catch (e) {
          console.log(e);
        }
      }

      upload.addEventListener("click", () => {
        data = document.getElementById("file").files[0];
        putObject(data);
      });
    </script>
  </body>
</html>

JS分片上传OSS

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>

  <body>
    <button id="submit">上传</button>
    <input id="file" type="file" />
    <!--导入sdk文件-->
    <script
      type="text/javascript"
      src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"
    ></script>
    <script type="text/javascript">
      const client = new OSS({
        // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
        region: "oss-cn-hangzhou",
        // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
        accessKeyId: "刚刚获取的id",
        accessKeySecret: "刚刚获取的secret",
        // 从STS服务获取的安全令牌(SecurityToken)。
        stsToken: "刚刚获取的token",
        // 填写Bucket名称,例如examplebucket。
        bucket: "test",
      });

      const headers = {
        // 指定该Object被下载时的网页缓存行为。
        "Cache-Control": "no-cache",
        // 指定该Object被下载时的名称。
        "Content-Disposition": "111.mp4",
        // 指定该Object被下载时的内容编码格式。
        "Content-Encoding": "utf-8",
        // 指定过期时间,单位为毫秒。
        "Expires": "1000",
        // 指定Object的存储类型。
        "x-oss-storage-class": "Standard",
        // 指定Object标签,可同时设置多个标签。
        "x-oss-tagging": "Tag1=1&Tag2=2",
        // 指定初始化分片上传时是否覆盖同名Object。此处设置为true,表示禁止覆盖同名Object。
        "x-oss-forbid-overwrite": "true",
      };

      // 指定上传到examplebucket的Object名称,例如exampleobject.txt。
      const name = "111.mp4";
      // 获取DOM。
      const submit = document.getElementById("submit");
      const options = {
        // 获取分片上传进度、断点和返回值。
        progress: (p, cpt, res) => {
          console.log(p);
        },
        // 设置并发上传的分片数量。
        parallel: 4,
        // 设置分片大小。默认值为1 MB,最小值为100 KB。
        partSize: 1024 * 1024,
        // headers,
        // 自定义元数据,通过HeadObject接口可以获取Object的元数据。
        meta: { year: 2020, people: "test" },
        mime: "text/plain",
      };

      // 监听按钮。
      submit.addEventListener("click", async () => {
        try {
          const data = document.getElementById("file").files[0];
          // 分片上传。
          const res = await client.multipartUpload(name, data, {
            ...options,
            // 设置上传回调。
      
          });
          console.log(res)
        } catch (err) {
          console.log(err);
        }
      });
    </script>
  </body>
</html>

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

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

相关文章

短视频配音的秘诀!你不会还在傻傻自己人声配音吧?

我们在刷短视频的时候&#xff0c;常常发现这些视频的声音很相似&#xff0c;难道都是同一个作者创作的吗&#xff1f; 其实&#xff0c;这都是他们通过AI智能配音技术&#xff0c;把文本转换为人工智能的声音&#xff0c;而非创作者本人的配音效果。 毕竟真人配音的效率太低…

Elasticsearch_分词器、搜索文档以及原生JAVA操作

文章目录一、ES分词器1、默认分词器2、IK分词器2.1 IK分词器安装及测试2.2 IK分词器词典3、拼音分词器4、自定义分词器二、搜索文档1、添加文档数据2、搜索方式3、ES搜索文档的过滤处理3.1 结果排序3.2 分页查询3.3 高亮查询3.4 SQL查询三、原生JAVA操作ES1、搭建项目2、索引操…

CIMCAl photo container detect is free, container damage detect

飞瞳引擎™小程序直接拍照识别集装箱/API接口二次开发集装箱信息识别/铅封号识别API免费顶尖AI集装箱箱号识别率99.98%以上&#xff0c;高泛化CIMCAIl ENGINE™ photo container detection is free&#xff0c;support API further development or WeChat applet,the recogniti…

Color correction for tone mapping

Abstract色调映射算法提供了复杂的方法&#xff0c;将真实世界的亮度范围映射到输出介质的亮度范围&#xff0c;但它们经常导致颜色外观的变化。在本研究中&#xff0c;我们进行了一系列的主观外观匹配实验&#xff0c;以测量对比度压缩和增强后图像色彩的变化。结果表明&#…

K8S 部署 Redis-Cluster 集群

本文使用 bitnami 镜像部署 redis-cluster 官方文档&#xff1a;https://github.com/bitnami/charts/tree/main/bitnami/redis-cluster 添加 bitnami 仓库 helm repo add bitnami https://charts.bitnami.com/bitnami自定义 values.yaml storageClass&#xff1a;集群的存储…

GBDT(梯度提升树,Gradient Boosting Decision Tree)

GBDT(Gradient Boosting Decision Tree)在数据分析和预测中的效果很好。它是一种基于决策树的集成算法。其中Gradient Boosting 是集成方法boosting中的一种算法&#xff0c;通过梯度下降来对新的学习器进行迭代。而GBDT中采用的就是CART决策树 一、Boosting Boosting指把多个…

一周搞定模拟电路视频教程,拒绝讲PPT,仿真软件配合教学,真正一周搞定

目录1、灵魂拷问2、懦夫救星3、福利领取2、使用流程1、灵魂拷问 问&#xff1a;模拟电路很难吗&#xff1f; 答&#xff1a;嗯&#xff0c;真的很难&#xff01;&#xff01;&#xff01; 问&#xff1a;模拟电路容易学吗&#xff1f; 答&#xff1a;很难学&#xff0c;建议放…

微电影广告具有哪些特点?

微电影广告是广告主投资的&#xff0c;以微电影为形式载体&#xff0c;以新媒体为主要传播载体&#xff0c;综合运用影视创作手法拍摄的集故事性、艺术性和商业性于一体的广告。它凭借精彩的电影语言和强大的明星效应多渠道联动传播&#xff0c;润物细无声地渗透和传递着商品信…

Tomcat介绍

Tomcat介绍 tomcat是一个免费的&#xff0c;开放源代码的Web应用服务器&#xff0c;是Apache软件基金会项目中的一个核心项目&#xff0c;由Apache &#xff0c;Sun和一些公司以及个人共同开发而成&#xff0c;深受Java爱好者的喜爱&#xff0c;是一款比较流行的web应用服务器…

【C++11】可变参数模板(函数模板、类模板)

在C11之前&#xff0c;类模板和函数模板只能含有固定数量的模板参数。C11增强了模板功能&#xff0c;允许模板定义中包含0到任意个模板参数&#xff0c;这就是可变参数模板。可变参数模板的加入使得C11的功能变得更加强大&#xff0c;而由此也带来了许多神奇的用法。 可变参数模…

buu [BJDCTF2020]signin 1

题目描述&#xff1a; 题目分析&#xff1a; 打开发现是16 进制数&#xff08;我也不知道我是怎么发现的&#xff0c;先是尝试了md5和rot-n,发现都不行&#xff0c;然后参考大佬的才知道是16进制&#xff09;使用 在线16进制转字符串 便能得到 flag但我如果不想用线上工具&…

当搭建nginx服务时启动闪退,访问不了服务器

在学习nginx搭建集群服务器时遇到了一些小困难&#xff0c;明明跟着教程视频来操作却启动出问题&#xff0c;闪退&#xff0c;然后访问不了服务器等问题&#xff0c;搞半天搞不清楚&#xff0c;不知道从何下手&#xff1f;当你也遇到这样的情况&#xff0c;或许我这里可以给出一…

网络有线无线配置

一、需求 在无线接入区内&#xff0c;当Lsw1的上联口出现故障时&#xff0c;需要通过AP1-LSw1-LSw2-LSw3的路径访问公网server3。这是因为AP1通过无线网连接到LSw1&#xff0c;而LSw1与LSw3之间的链路出现故障&#xff0c;无法直接访问公网server3。因此&#xff0c;流量需要通…

02-18 周六 图解机器学习之SMV 第五章5-2

02-18 周六 图解机器学习之SMV 第五章5-2时间版本修改人描述2023年2月18日11:47:18V0.1宋全恒新建文档 环境 程序的基本环境&#xff0c;是使用了jupyter&#xff0c;在容器中运行的。 简介 本程序主要演示支持向量的获取&#xff0c;支持向量是距离超平面最近的点组成的。程序…

django+celery+ RabbitMQ自定义多个消息队列

关于django celery的使用网上有很多文章&#xff0c;本文就不多做更多的说明。 本文使用版本 python3.8.15 Django3.2.4 celery5.2.7celery.py from __future__ import absolute_import, unicode_literals import os from celery import Celery from kombu import Exchange, …

XC7K70T-1FBG484C, XC7A50T-1CSG324I FPGA,Kintex-7 285 I/O

说明Kintex-7 FPGA为快速增长应用和无线通信提供最优性价比和低功耗。Kintex-7 FPGA具有卓越的性能和连接性&#xff0c;与前一代相比&#xff0c;优化了最佳性价比&#xff0c;提高了2倍&#xff0c;实现了新一类fpga。Kintex-7内置支持8通道PCI Express (Gen1/Gen2)&#xff…

RPC框架dubbo的学习

一、基础知识 1、分布式基础理论 1.1&#xff09;、什么是分布式系统&#xff1f; 《分布式系统原理与范型》定义&#xff1a; “分布式系统是若干独立计算机的集合&#xff0c;这些计算机对于用户来说就像单个相关系统” 分布式系统&#xff08;distributed system&#…

Linux驱动开发—设备树开发详解

设备树开发详解 设备树概念 Device Tree是一种描述硬件的数据结构&#xff0c;以便于操作系统的内核可以管理和使用这些硬件&#xff0c;包括CPU或CPU&#xff0c;内存&#xff0c;总线和其他一些外设。 Linux内核从3.x版本之后开始支持使用设备树&#xff0c;可以实现驱动代…

Vue3后台管理系统(四)SVG图标

目录 一、安装 vite-plugin-svg-icons 二、创建图标文件夹 三、main.ts 引入注册脚本 四、vite.config.ts 插件配置 五、TypeScript支持 六、组件封装 七、使用 Element Plus 图标库往往满足不了实际开发需求&#xff0c;可以引用和使用第三方例如 iconfont 的图标&…

Java数组,超详细整理,适合新手入门

目录 一、什么是Java中的数组&#xff1f; 二、数组有哪些常见的操作&#xff1f; 三、数组的五种赋值方法和使用方法 声明数组 声明数组并且分配空间 声明数组同时赋值(1) 声明数组同时赋值(2) 从控制台输入向数组赋值 四、求总和平均 五、求数组中最大值最小值 六…