Multipartfile判断文件类型的简单处理办法。

news2024/11/13 15:01:18

通过浏览器上传的文件在后台需要验证文件类型。如果单纯匹配后缀名的方式是有风险的,容易被换了后缀的病毒文件给破坏掉。

比如:

 如果我上传已修改的文件。(把xlsx改成了jpg)

这样,无法识别出来真实的内容。

 

 所以为了避免这种情况。可以获取文件前面的四个字节内容去进行判断。

public class FileTypeUtils {

    public final static Map<String, String> FILE_TYPE_MAP = new HashMap<String, String>();

    static {
        //只处理表格内容
 
        FILE_TYPE_MAP.put("504b0304140006000800", "docx");// docx文件
        FILE_TYPE_MAP.put("504B03040A0000000000","xlsx");//xlsx文件
        FILE_TYPE_MAP.put("d0cf11e0a1b11ae10000", "wps");// WPS文字wps、表格et、演示dps都是一样的

        FILE_TYPE_MAP.put("FFD8FF", "jpg"); // JPEG (jpg)
        FILE_TYPE_MAP.put("89504E47", "png"); // PNG (png)
        FILE_TYPE_MAP.put("47494638", "gif"); // GIF (gif)
        FILE_TYPE_MAP.put("49492a00227105008037", "tif"); // TIFF (tif)
        FILE_TYPE_MAP.put("424d228c010000000000", "bmp"); // 16色位图(bmp)
        FILE_TYPE_MAP.put("424d8240090000000000", "bmp"); // 24位位图(bmp)
        FILE_TYPE_MAP.put("424d8e1b030000000000", "bmp"); // 256色位图(bmp)
        FILE_TYPE_MAP.put("41433130313500000000", "dwg"); // CAD (dwg)

        FILE_TYPE_MAP.put("68746D6C3E", "html"); // HTML (html)
        FILE_TYPE_MAP.put("48544d4c207b0d0a0942", "css"); // css
        FILE_TYPE_MAP.put("696b2e71623d696b2e71", "js"); // js
        FILE_TYPE_MAP.put("7b5c727466315c616e73", "rtf"); // Rich Text Format
        // (rtf)
        FILE_TYPE_MAP.put("38425053000100000000", "psd"); // Photoshop (psd)
        FILE_TYPE_MAP.put("44656C69766572792D646174653A", "eml"); // Email
        FILE_TYPE_MAP.put("d0cf11e0a1b11ae10000", "doc"); // MS Excel
        // 注意:word、msi 和
        // excel的文件头一样
        FILE_TYPE_MAP.put("d0cf11e0a1b11ae10000", "vsd"); // Visio 绘图
        FILE_TYPE_MAP.put("5374616E64617264204A", "mdb"); // MS Access (mdb)
        FILE_TYPE_MAP.put("252150532D41646F6265", "ps");
        FILE_TYPE_MAP.put("255044462d312e", "pdf");
        FILE_TYPE_MAP.put("75736167", "txt");

        FILE_TYPE_MAP.put("2e524d46000000120001", "rmvb"); // rmvb/rm相同
        FILE_TYPE_MAP.put("464c5601050000000900", "flv"); // flv与f4v相同
        FILE_TYPE_MAP.put("00000020667479706d70", "mp4");
        FILE_TYPE_MAP.put("49443303000000002176", "mp3");
        FILE_TYPE_MAP.put("000001b", "mpg"); //MPEG (mpg),文件头:000001BA MPEG (mpg),文件头:000001B3
        FILE_TYPE_MAP.put("3026b2758e66cf11a6d9", "wmv"); // wmv与asf相同
        FILE_TYPE_MAP.put("57415645", "wav"); // Wave (wav)
        FILE_TYPE_MAP.put("41564920", "avi");

        FILE_TYPE_MAP.put("4d546864", "mid"); // MIDI (mid)
        FILE_TYPE_MAP.put("504b0304", "zip");
        FILE_TYPE_MAP.put("52617221", "rar");
        FILE_TYPE_MAP.put("235468697320636f6e66", "ini");
        FILE_TYPE_MAP.put("504b03040a0000000000", "jar");
        FILE_TYPE_MAP.put("4d5a9000030000000400", "exe");// 可执行文件

        FILE_TYPE_MAP.put("3c25402070616765206c", "jsp");// jsp文件
        FILE_TYPE_MAP.put("4d616e69666573742d56", "mf");// MF文件
        FILE_TYPE_MAP.put("3C3F786D6C", "xml");// xml文件
        FILE_TYPE_MAP.put("494e5345525420494e54", "sql");// xml文件
        FILE_TYPE_MAP.put("7061636b616765207765", "java");// java文件
        FILE_TYPE_MAP.put("406563686f206f66660d", "bat");// bat文件
        FILE_TYPE_MAP.put("1f8b0800000000000000", "gz");// gz文件
        FILE_TYPE_MAP.put("6c6f67346a2e726f6f74", "properties");// bat文件
        FILE_TYPE_MAP.put("cafebabe0000002e0041", "class");// bat文件
        FILE_TYPE_MAP.put("49545346030000006000", "chm");// bat文件
        FILE_TYPE_MAP.put("04000000010000001300", "mxp");// bat文件
        FILE_TYPE_MAP.put("6431303a637265617465", "torrent");
        FILE_TYPE_MAP.put("6D6F6F76", "mov"); // Quicktime (mov)
        FILE_TYPE_MAP.put("FF575043", "wpd"); // WordPerfect (wpd)
        FILE_TYPE_MAP.put("CFAD12FEC5FD746F", "dbx"); // Outlook Express (dbx)
        FILE_TYPE_MAP.put("2142444E", "pst"); // Outlook (pst)
        FILE_TYPE_MAP.put("AC9EBD8F", "qdf"); // Quicken (qdf)
        FILE_TYPE_MAP.put("E3828596", "pwl"); // Windows Password (pwl)
        FILE_TYPE_MAP.put("2E7261FD", "ram"); // Real Audio (ram)
        FILE_TYPE_MAP.put("2E524D46", "rm");
    }

    /**
     * 得到上传文件的文件头
     *
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF; // 去除高位0, 03,80
            String hv = Integer.toHexString(v).toUpperCase(); // 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式,并转换为大写
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        System.out.println(stringBuilder.toString());
        return stringBuilder.toString();
    }

    /**
     * 获取文件类型,查询前四位字节,但是office三个文件的前缀超过四位字节相同,
     * 因此这里先判断是什么类型,再去处理要查询的字节长度
     *
     * @param inputStream
     * @return
     */
    public static String getFileType(InputStream inputStream) {
        byte[] b =  new byte[4];
      
        String res = null;
        try {
            inputStream.read(b, 0, b.length);
            String fileCode = bytesToHexString(b);
            log.info(fileCode);
            // 这种方法在字典的头代码不够位数的时候可以用但是速度相对慢一点
            Iterator<String> keyIter = FILE_TYPE_MAP.keySet().iterator();
            while (keyIter.hasNext()) {
                String key = keyIter.next();
                if (key.toUpperCase().startsWith(fileCode)) {
                    res = FILE_TYPE_MAP.get(key);
                    break;
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("文件读取异常", e);
        }
        return res;
    }
}

尝试:

现在可以判断修改了后缀名的文件。

 

 但是还有一个问题。

但是这样获取的类型大部分都可以,docx 、xlsx 这类却无法进行区分。因为获取的前四个字节内容是一致的。

因此我在原有判断的基础上进行了修改。

在判断第五位的时候就会出现区别(仅限于xlsx和docx    |   pptx无法判断,在这里是个问题)

所以我把数据长度根据后缀名称类型重新进行了判断,docx和xlsx需要判断五个字节,而其他只需要四个字节。

 /**
     * 获取文件类型,查询前四位字节,但是office三个文件的前缀超过四位字节相同,
     * 因此这里先判断是什么类型,再去处理要查询的字节长度
     *
     * @param inputStream
     * @return
     */
    public static String getFileType(InputStream inputStream,String suffix) {
        byte[] b = null;
        switch (suffix.toLowerCase()){
            case "docx":
            case "xlsx":
                b = new byte[5];
                break;
            default:
                b = new byte[4];
                break;
        }
        String res = null;
        try {
            inputStream.read(b, 0, b.length);
            String fileCode = bytesToHexString(b);
            log.info(fileCode);
            // 这种方法在字典的头代码不够位数的时候可以用但是速度相对慢一点
            Iterator<String> keyIter = FILE_TYPE_MAP.keySet().iterator();
            while (keyIter.hasNext()) {
                String key = keyIter.next();
                if (key.toUpperCase().startsWith(fileCode)) {
                    res = FILE_TYPE_MAP.get(key);
                    break;
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("文件读取异常", e);
        }
        return res.toLowerCase();
    }

这样在判断 docx 和xlsx 以及其他需要使用的文件的时候就可以分别区分了。(目前只是满足了我自己的实际需求,如果有其他文件要判断。可能要调整判断的长度)

 

修改后的完整代码如下:

 

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
public class FileTypeUtils {

    public final static Map<String, String> FILE_TYPE_MAP = new HashMap<String, String>();

    static {
        //只处理表格内容
        FILE_TYPE_MAP.put("C4EABCB6","csv");//CSV
        FILE_TYPE_MAP.put("504b0304140006000800", "docx");// docx文件
        FILE_TYPE_MAP.put("504B03040A0000000000","xlsx");//xlsx文件
        FILE_TYPE_MAP.put("d0cf11e0a1b11ae10000", "wps");// WPS文字wps、表格et、演示dps都是一样的

       /* FILE_TYPE_MAP.put("FFD8FF", "jpg"); // JPEG (jpg)
        FILE_TYPE_MAP.put("89504E47", "png"); // PNG (png)
        FILE_TYPE_MAP.put("47494638", "gif"); // GIF (gif)
        FILE_TYPE_MAP.put("49492a00227105008037", "tif"); // TIFF (tif)
        FILE_TYPE_MAP.put("424d228c010000000000", "bmp"); // 16色位图(bmp)
        FILE_TYPE_MAP.put("424d8240090000000000", "bmp"); // 24位位图(bmp)
        FILE_TYPE_MAP.put("424d8e1b030000000000", "bmp"); // 256色位图(bmp)
        FILE_TYPE_MAP.put("41433130313500000000", "dwg"); // CAD (dwg)

        FILE_TYPE_MAP.put("68746D6C3E", "html"); // HTML (html)
        FILE_TYPE_MAP.put("48544d4c207b0d0a0942", "css"); // css
        FILE_TYPE_MAP.put("696b2e71623d696b2e71", "js"); // js
        FILE_TYPE_MAP.put("7b5c727466315c616e73", "rtf"); // Rich Text Format
        // (rtf)
        FILE_TYPE_MAP.put("38425053000100000000", "psd"); // Photoshop (psd)
        FILE_TYPE_MAP.put("44656C69766572792D646174653A", "eml"); // Email
        FILE_TYPE_MAP.put("d0cf11e0a1b11ae10000", "doc"); // MS Excel
        // 注意:word、msi 和
        // excel的文件头一样
        FILE_TYPE_MAP.put("d0cf11e0a1b11ae10000", "vsd"); // Visio 绘图
        FILE_TYPE_MAP.put("5374616E64617264204A", "mdb"); // MS Access (mdb)
        FILE_TYPE_MAP.put("252150532D41646F6265", "ps");
        FILE_TYPE_MAP.put("255044462d312e", "pdf");
        FILE_TYPE_MAP.put("75736167", "txt");

        FILE_TYPE_MAP.put("2e524d46000000120001", "rmvb"); // rmvb/rm相同
        FILE_TYPE_MAP.put("464c5601050000000900", "flv"); // flv与f4v相同
        FILE_TYPE_MAP.put("00000020667479706d70", "mp4");
        FILE_TYPE_MAP.put("49443303000000002176", "mp3");
        FILE_TYPE_MAP.put("000001b", "mpg"); //MPEG (mpg),文件头:000001BA MPEG (mpg),文件头:000001B3
        FILE_TYPE_MAP.put("3026b2758e66cf11a6d9", "wmv"); // wmv与asf相同
        FILE_TYPE_MAP.put("57415645", "wav"); // Wave (wav)
        FILE_TYPE_MAP.put("41564920", "avi");

        FILE_TYPE_MAP.put("4d546864", "mid"); // MIDI (mid)
        FILE_TYPE_MAP.put("504b0304", "zip");
        FILE_TYPE_MAP.put("52617221", "rar");
        FILE_TYPE_MAP.put("235468697320636f6e66", "ini");
        FILE_TYPE_MAP.put("504b03040a0000000000", "jar");
        FILE_TYPE_MAP.put("4d5a9000030000000400", "exe");// 可执行文件

        FILE_TYPE_MAP.put("3c25402070616765206c", "jsp");// jsp文件
        FILE_TYPE_MAP.put("4d616e69666573742d56", "mf");// MF文件
        FILE_TYPE_MAP.put("3C3F786D6C", "xml");// xml文件
        FILE_TYPE_MAP.put("494e5345525420494e54", "sql");// xml文件
        FILE_TYPE_MAP.put("7061636b616765207765", "java");// java文件
        FILE_TYPE_MAP.put("406563686f206f66660d", "bat");// bat文件
        FILE_TYPE_MAP.put("1f8b0800000000000000", "gz");// gz文件
        FILE_TYPE_MAP.put("6c6f67346a2e726f6f74", "properties");// bat文件
        FILE_TYPE_MAP.put("cafebabe0000002e0041", "class");// bat文件
        FILE_TYPE_MAP.put("49545346030000006000", "chm");// bat文件
        FILE_TYPE_MAP.put("04000000010000001300", "mxp");// bat文件
        FILE_TYPE_MAP.put("6431303a637265617465", "torrent");
        FILE_TYPE_MAP.put("6D6F6F76", "mov"); // Quicktime (mov)
        FILE_TYPE_MAP.put("FF575043", "wpd"); // WordPerfect (wpd)
        FILE_TYPE_MAP.put("CFAD12FEC5FD746F", "dbx"); // Outlook Express (dbx)
        FILE_TYPE_MAP.put("2142444E", "pst"); // Outlook (pst)
        FILE_TYPE_MAP.put("AC9EBD8F", "qdf"); // Quicken (qdf)
        FILE_TYPE_MAP.put("E3828596", "pwl"); // Windows Password (pwl)
        FILE_TYPE_MAP.put("2E7261FD", "ram"); // Real Audio (ram)
        FILE_TYPE_MAP.put("2E524D46", "rm");*/
    }

    /**
     * 得到上传文件的文件头
     *
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF; // 去除高位0, 03,80
            String hv = Integer.toHexString(v).toUpperCase(); // 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式,并转换为大写
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        System.out.println(stringBuilder.toString());
        return stringBuilder.toString();
    }

    /**
     * 获取文件类型,查询前四位字节,但是office三个文件的前缀超过四位字节相同,
     * 因此这里先判断是什么类型,再去处理要查询的字节长度
     *
     * @param inputStream
     * @return
     */
    public static String getFileType(InputStream inputStream,String suffix) {
        byte[] b = null;
        switch (suffix.toLowerCase()){
            case "docx":
            case "xlsx":
                b = new byte[5];
                break;
            default:
                b = new byte[4];
                break;
        }
        String res = null;
        try {
            inputStream.read(b, 0, b.length);
            String fileCode = bytesToHexString(b);
            log.info(fileCode);
            // 这种方法在字典的头代码不够位数的时候可以用但是速度相对慢一点
            Iterator<String> keyIter = FILE_TYPE_MAP.keySet().iterator();
            while (keyIter.hasNext()) {
                String key = keyIter.next();
                if (key.toUpperCase().startsWith(fileCode)) {
                    res = FILE_TYPE_MAP.get(key);
                    break;
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("文件读取异常", e);
        }
        return res.toLowerCase();
    }
}

尚未解决的问题:

1、xls、doc如何判断

2、如果使用Apache Tika 会不会快一点。

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

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

相关文章

java基础巩固-宇宙第一AiYWM:为了维持生计,架构知识+分布式微服务+高并发高可用高性能知识序幕就此拉开(六:Hystrix之熔断、降级、限流)~整起

Hystrix 中文文档&#xff1a;https://www.apiref.com/spring-cloud-zh/dalston/#_circuit_breaker_hystrix_clients服务雪崩&#xff1a;服务 A 调用了服务 B&#xff0c;服务 B 再调用了服务 C&#xff0c;但是因为某些原因&#xff0c;服务 C 顶不住了&#xff0c;这个时候大…

Strimzi Kafka Bridge(桥接)实战之三:自制sdk(golang版本)

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 本篇概览 本文是《Strimzi Kafka Bridge(桥接)实战》的第三篇&#xff0c;前文咱们掌握了Strimzi Kafka Bridge的基本功能&#xff1a;基于http提供各种kafk…

特海国际通过港交所上市聆讯:翻台率下滑明显,张勇夫妇为实控人

撰稿|汤汤 来源|贝多财经 近日&#xff0c;海底捞&#xff08;HK:06862&#xff09;海外业务分拆公司特海国际控股有限公司&#xff08;下称“特海国际”&#xff09;通过港交所上市聆讯。据贝多财经了解&#xff0c;特海国际将以介绍形式于港交所主板上市。所谓介绍形式&…

数据挖掘Java——Apriori算法的实现

一、Apriori算法的前置知识 Apriori算法是一种挖掘关联规则的频繁项集算法&#xff0c;其核心思想是通过候选集生成和向下封闭检测两个阶段来挖掘频繁项集。 关联规则挖掘是数据挖掘中最活跃的研究方法之一&#xff0c;最初的动机是针对购物篮分析问题提出的&#xff0c;其目…

[附源码]Node.js计算机毕业设计工会会员管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

【Linux学习】多线程

目录前言一、初识线程1. 线程的概念2. 线程的优缺点3. 线程异常4. 线程的用途二、Linux中的线程和进程1. 进程和线程的区别2. 进程中的线程共享三、Linux线程控制1. POSIX线程库2. 创建线程3. 线程终止4. 线程等待5. 线程分离四、Linux线程互斥1. 线程互斥的概念2. 互斥量mutex…

蓝桥杯基础算法(一)—— 快速排序

文章目录1. 基本思想2. 图解过程3. 代码模板4. 例题讲解&#x1f351; 快速排序&#x1f351; 第 k 个数1. 基本思想 快速排序是 Hoare 于 1962年 提出的一种二叉树结构的交换排序方法。 其基本思想为&#xff1a; &#xff08;1&#xff09;确定分界点&#xff1a;在数组中…

从零开始的MySQL(1)

目录1.MySQL的安装2.MySQL的基本操作2.1 展示数据库2.2 创建数据库2.3 选中数据库2.4 删除数据库2.5 常用数据类型2.5.1 整形2.5.2 浮点数2.6 创建表2.7 查看表2.7 查看表结构2.8 删除表3.数据库增删改查3.1 单行插入3.2 多行插入3.3 插入日期3.4 select查询3.4.1 select3.4.2 …

Jprofiler监控服务器的cpu

现象&#xff1a;压测过程中&#xff0c;发现应用服务器的cpu使用率比较高>80%&#xff0c;我们就可以判断服务器的cpu使用率太高了。 一般cpu太高有两种情况&#xff0c; 1.接口的性能非常好&#xff0c;比如响应时间<10ms&#xff0c;tps很高&#xff0c;此时的cpu使用…

CSDN官方插件猿如意可以用ChatGPT啦!

什么是 ChatGPT Chat GPT 是一种由 AI 技术驱动的自然语言处理工具&#xff0c;可让您与聊天机器人进行类似人类的对话等它是基于OpenAI的GPT-3架构进行构建的&#xff0c;并经过训练&#xff0c;以便能够回答人类的问题并进行自然对话ChatGPT可以回答关于各种话题的问题&#…

基于SSM广州旅游攻略网站的设计与实现

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;

【Unity】摄像机跟随鼠标移动以物体为中心旋转 物体根据视线方向移动

描述 实现摄像机根据鼠标移动跟随物体旋转&#xff0c;以摄像机前物体为中心&#xff0c;摄像机围绕物体旋转&#xff0c;并使摄像机时刻指向物体 实现效果 Unity 组件设置 Camera 组件设置 Body 组件设置 实现代码 CameraRotateMove.cs 摄像机跟随和旋转 using System.Co…

神经网络常用的训练方式,什么是神经网络训练法

1、神经网络中的模型训练是什么意思? 无导师学习网络 神经网络中的模型训练是通过自动寻找样本中的内在规律和本质属性,自组织、自适应地改变网络参数与结构。 神经网络在系统辨识、模式识别、智能控制等领域有着广泛而吸引人的前景&#xff0c;特别在智能控制中&#xff0c;…

寄存器内存读写指令(二) —— 多寄存器读写 LDM / STM

有的时候&#xff0c;CPU可能会遇到 a; b; c&#xff0c;这个时候为了提升效率&#xff0c;CPU可能会一次将多个寄存器里的变量保存到内存中。这个时候之前介绍的 LDR / STR 指令虽然也能实现&#xff0c;但只能操作一个寄存器的读写。 因此&#xff0c;考虑到这点&#xff0c…

基于FPGA的PWM发生器设计

目录 引言 设计说明 设计特点 设计思路 设计源码 整数除法模块

超级好看的 Edge 浏览器新标签页插件:好用、好看、免费浏览器必备

BdTab 新标签页 BdTab新标签页扩展是一款免费无广告、简单好用的的高颜值新标签页扩展。 BdTab它颜值高、简单好用、支持高度自定义&#xff1a; 在登录之后支持云备份&#xff0c;支持快速切换搜索引擎&#xff0c;支持快速查看浏览历史记录和书签&#xff0c;用起来非常方便…

数据结构与算法——Java实现排序算法(一)

目录 一、排序算法 1.1 排序算法基本介绍 1.2 衡量程序执行的方法 1.2.1 事后统计法 1.2.2 事前估算的方法 二、 时间复杂度 2.1 时间频度 2.2 时间复杂度 2.2.1 常见的时间复杂度 2.2.2 常数阶O(1) 2.2.3 对数阶O(log2底n) 2.2.4 线性阶O(n) 2.2.5 线性对数阶O(n…

2022年PAT冬季甲级考试 25 A-3 Articulation Points

A-3 Articulation Points 分数 25 In graph theory, given a connected graph G, the vertices whose removal would disconnect G are known as articulation points. For example, vertices 1, 3, 5, and 7 are the articulation points in the graph shown by the above fi…

WAYON维安功率肖特基二极管,适配器领域的助推器

WAYON维安功率肖特基二极管&#xff0c;适配器领域的助推器。 维安功率肖特基二极管&#xff0c;适配器领域的助推器 导言 肖特基二极管&#xff0c;是以它的发明人肖特基博士名字而命名的&#xff0c;又被称作是肖特基势垒二极管。它是金属与半导体材料相互接触&#xff0c;且…

C++:类和对象:C++对象模型和 this指针

1&#xff1a;成员变量和成员函数分开存储 在C中&#xff0c;类内的成员变量和成员函数分开存储&#xff0c;只有非静态成员变量才属于类对象。 案例&#xff1a;我们写一个空类&#xff0c;然后创建一个对象&#xff0c;看看这个空对象占用多大空间。 #include<iostream…