当前位置: 首页 > news >正文

大文件上传

上图就是大致的流程


一、标题图片

  1. 上传课程的标题图片

  1. Ajax发送请求到后端

  1. 后端接收到图片使用IO流去保存图片,返回图片的信息对象

  1. JS回调函数接收对象通过$("元素id").val(值),方式给页面form表达img标签src属性值,达到上传图片并回显

二、大文件上传(流媒体、音频、.zip文件等)

  1. 页面div点击事件,选中一个视频文件

  1. JS判断文件大小,判断文件类型是否合法

3.JS循环切片,计算总片数,计算每一片的起始位置,循环上传

4.发送Ajax转给后端切片

5.后端接收并创建临时目录存放

    /*** 分片上传,前端调用此方法* @param request* @param guid* @param chunk* @param file* @return*/@PostMapping("/uploadSlice")@ResponseBodypublic ResponseResult<?> uploadSlice2(HttpServletRequest request, @RequestParam("guid") String guid,@RequestParam("chunk") Integer chunk,@RequestParam("file") MultipartFile file) {if (this.uploadSlice(request, guid, chunk, file)){return ResponseResultUtils.genResult("上传成功","");}else{return ResponseResultUtils.genErrorResult("上传失败");}}/*** 分片上传的具体方法* @param request* @param guid* @param chunk* @param file* @return*/private boolean uploadSlice(HttpServletRequest request, String guid, Integer chunk, MultipartFile file) {try {boolean isMultipart = ServletFileUpload.isMultipartContent(request);logger.info("isMultipart = {}",isMultipart);if (isMultipart) {if (chunk == null){chunk = 0;}// 临时目录用来存放所有分片文件String tempFileDir =  rootFilePath + bigPath + guid;File parentFileDir = new File(tempFileDir);if (!parentFileDir.exists()) {parentFileDir.mkdirs();}logger.info("接到上传的分片文件,{},{},{}",guid,chunk,tempFileDir);// 分片处理时,前台会多次调用上传接口,每次都会上传文件的一部分到后台File tempPartFile = new File(parentFileDir, guid + "_" + chunk + ".part");FileUtils.copyInputStreamToFile(file.getInputStream(), tempPartFile);}} catch (Exception e) {return false;}return true;}

6.计数器变量值=总片数时,发送合并请求

7.后端合并

/*** 分片文件合并,前端调用此方法* @param guid* @param fileName* @return*/@RequestMapping("/uploadMerge")@ResponseBodypublic ResponseResult<?> uploadMerge2(@RequestParam("guid") String guid, @RequestParam("fileName") String fileName) {// 得到 destTempFile 就是最终的文件SpaceImage image = this.uploadMerge(guid, fileName);if(null != imageSpaceImage){return ResponseResultUtils.genResult(imageSpaceImage,"合并成功");}else{return ResponseResultUtils.genErrorResult("合并文件失败");}}private ImageSpaceImage uploadMerge(String guid, String fileName){SpaceImage image = mergeFile(guid, fileName);//此处需要注意,OSS需要再次切片上传,但minIO是不用得,它默认5M超过就会自动切片String path = "";//移除文件poolTaskExecutor.execute(() -> {com.eyang.ecpp.utils.FileUtils.deleteFile(rootFilePath+bigPath);});return imageSpaceImage;}private ImageSpaceImage mergeFile(String guid, String fileName) {logger.info("接到上传的分片文件合并请求,{},{}",guid,fileName);try {String sName = fileName.substring(fileName.lastIndexOf("."));//时间格式化格式Date currentTime = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");//获取当前时间并作为时间戳String timeStamp = simpleDateFormat.format(currentTime);//拼接新的文件名String newName = timeStamp + sName;simpleDateFormat = new SimpleDateFormat("yyyyMM");String tempPath = rootFilePath + bigPath+guid;String margePath = rootFilePath + bigPath+simpleDateFormat.format(currentTime);File parentFileDir = new File(tempPath);if (parentFileDir.isDirectory()) {File destTempFile = new File(margePath, newName);if (!destTempFile.exists()) {//先得到文件的上级目录,并创建上级目录,在创建文件destTempFile.getParentFile().mkdir();destTempFile.createNewFile();}for (int i = 0; i < Objects.requireNonNull(parentFileDir.listFiles()).length; i++) {File partFile = new File(parentFileDir, guid + "_" + i + ".part");FileOutputStream destTempfos = new FileOutputStream(destTempFile, true);//遍历"所有分片文件"到"最终文件"中FileUtils.copyFile(partFile, destTempfos);destTempfos.close();}// 删除临时目录中的分片文件FileUtils.deleteDirectory(parentFileDir);String[] resultArr = FileStorageUtils.saveBigFile(Files.readAllBytes(Paths.get(destTempFile.getPath())), com.eyang.ecpp.utils.FileUtils.getExtension(destTempFile.getName()));ImageSpaceImage imageSpaceImage = new ImageSpaceImage();//第一个是组名 第二个是改后的文件名imageSpaceImage.setImgUrl(margePath+"/"+newName);//imageSpaceImage.setName(destTempFile.getName());imageSpaceImage.setName(fileName);return imageSpaceImage;//destTempFile.getAbsolutePath();}} catch (Exception e) {logger.error("切片文件合并,失败原因e:{}", e.getMessage());}return null;}

8.合并成功后进行转码

转码需要下载一个ffmpeg,下载完解压打开bin目录,打开电脑的环境变量往path中添加上bin的目录即可。

还需要引入依赖

 <!--  视频编码 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>

9.转码发送请求

10.后端转码

/*** 视频编码** @param absolutePath 绝对路径* @return {@link ResponseResult}<{@link ?}>*/@RequiresPermissions("cms:article:edit")@RequestMapping(value = "video/coding")@ResponseBodypublic ResponseResult<?> videoCoding(@RequestParam String absolutePath) {TranscodeConfig transcodeConfig = new TranscodeConfig();//设置视频封面transcodeConfig.setPoster("1");transcodeConfig.setTsSeconds("60");ResponseResult<?> transResult = TranscodeFileUtils.transCodeFile(absolutePath, transcodeConfig);String retUrl = "";if (null != transResult) {Map<String, Object> data = (Map<String, Object>) transResult.getData();if (null != data) {Map<String, Object> videoInfo = (Map<String, Object>) data.get("data");if (null != videoInfo) {retUrl = (String) videoInfo.get("m3u8");}}}return ResponseResultUtils.genResult(retUrl,"转码成功");}

视频转码配置实体类

package com.utils;public class TranscodeConfig {private String poster; // 截取封面的时间private String tsSeconds; // ts分片大小,单位是秒private String cutStart; // 视频裁剪,开始时间private String cutEnd; // 视频裁剪,结束时间public String getPoster() {return poster;}public void setPoster(String poster) {this.poster = poster;}public String getTsSeconds() {return tsSeconds;}public void setTsSeconds(String tsSeconds) {this.tsSeconds = tsSeconds;}public String getCutStart() {return cutStart;}public void setCutStart(String cutStart) {this.cutStart = cutStart;}public String getCutEnd() {return cutEnd;}public void setCutEnd(String cutEnd) {this.cutEnd = cutEnd;}public TranscodeConfig() {}public TranscodeConfig(String poster, String tsSeconds, String cutStart, String cutEnd) {this.poster = poster;this.tsSeconds = tsSeconds;this.cutStart = cutStart;this.cutEnd = cutEnd;}
}

转码工具类

public class TranscodeFileUtils {/*** 视频根路径*/private static String videoFolder= Global.getConfig("video.folder");private static final Logger LOGGER = LoggerFactory.getLogger(TranscodeFileUtils.class);public static ResponseResult<Map<String, Object>> transCodeFile(String filePath, TranscodeConfig transcodeConfig){try {// 按照日期生成子目录String today = DateTimeFormatter.ofPattern("yyyyMMdd").format(LocalDate.now());String s = Identities.uuid2();Path targetFolder = Paths.get(videoFolder, today, s);// 执行转码操作LOGGER.info("开始转码");FFmpegUtils.transcodeToM3u8(filePath, targetFolder.toString(), transcodeConfig);// 封装结果Map<String, Object> videoInfo = new HashMap<>();videoInfo.put("m3u8", String.join("\\", targetFolder.toString(), "index.m3u8"));videoInfo.put("poster", String.join("\\", targetFolder.toString(), "poster.jpg"));Map<String, Object> result = new HashMap<>();result.put("success", true);result.put("data", videoInfo);return ResponseResultUtils.genResult(result,"转码成功!");} catch (Exception e) {e.printStackTrace();}return null;}public static void main(String[] args){System.out.println(TranscodeFileUtils.transCodeFile("E:\\录屏\\shipin\\test.mp4", new TranscodeConfig("00:00:00.001","15","","")));}}

转码工具类

public class FFmpegUtils {private static final Logger LOGGER = LoggerFactory.getLogger(FFmpegUtils.class);// 跨平台换行符private static final String LINE_SEPARATOR = System.getProperty("line.separator");/*** 生成随机16个字节的AESKEY* @return*/private static byte[] genAesKey ()  {try {KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");keyGenerator.init(128);return keyGenerator.generateKey().getEncoded();} catch (NoSuchAlgorithmException e) {return null;}}/*** 在指定的目录下生成key_info, key文件,返回key_info文件* @param folder* @throws IOException*/private static Path genKeyInfo(String folder) throws IOException {// AES 密钥byte[] aesKey = genAesKey();// AES 向量String iv = Hex.encodeHexString(genAesKey());// key 文件写入Path keyFile = Paths.get(folder, "key");Files.write(keyFile, aesKey, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);// key_info 文件写入StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("key").append(LINE_SEPARATOR);                    // m3u8加载key文件网络路径stringBuilder.append(keyFile.toString()).append(LINE_SEPARATOR);    // FFmeg加载key_info文件路径stringBuilder.append(iv);                                            // ASE 向量Path keyInfo = Paths.get(folder, "key_info");Files.write(keyInfo, stringBuilder.toString().getBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);return keyInfo;}/*** 指定的目录下生成 master index.m3u8 文件* @param file            master m3u8文件地址* @param indexPath            访问子index.m3u8的路径* @param bandWidth            流码率* @throws IOException*/private static void genIndex(String file, String indexPath, String bandWidth) throws IOException {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("#EXTM3U").append(LINE_SEPARATOR);stringBuilder.append("#EXT-X-STREAM-INF:BANDWIDTH=" + bandWidth).append(LINE_SEPARATOR);  // 码率stringBuilder.append(indexPath);Files.write(Paths.get(file), stringBuilder.toString().getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);}/*** 转码视频为m3u8* @param source                源视频* @param destFolder            目标文件夹* @param config                配置信息* @throws IOException* @throws InterruptedException*/public static void transcodeToM3u8(String source, String destFolder, TranscodeConfig config) throws IOException, InterruptedException {// 判断源视频是否存在if (!Files.exists(Paths.get(source))) {throw new IllegalArgumentException("文件不存在:" + source);}// 创建工作目录Path workDir = Paths.get(destFolder, "ts");Files.createDirectories(workDir);// 在工作目录生成KeyInfo文件Path keyInfo = genKeyInfo(workDir.toString());// 构建命令List<String> commands = new ArrayList<>();commands.add("ffmpeg");commands.add("-i");commands.add(source);                    // 源文件commands.add("-c:v");commands.add("libx264");                // 视频编码为H264commands.add("-c:a");commands.add("copy");                    // 音频直接copycommands.add("-hls_key_info_file");commands.add(keyInfo.toString());        // 指定密钥文件路径commands.add("-hls_time");commands.add(config.getTsSeconds());    // ts切片大小commands.add("-hls_playlist_type");commands.add("vod");                    // 点播模式commands.add("-hls_segment_filename");commands.add("%06d.ts");                // ts切片文件名称if (StringUtils.hasText(config.getCutStart())) {commands.add("-ss");commands.add(config.getCutStart());    // 开始时间}if (StringUtils.hasText(config.getCutEnd())) {commands.add("-to");commands.add(config.getCutEnd());        // 结束时间}commands.add("index.m3u8");                                                        // 生成m3u8文件// 构建进程Process process = new ProcessBuilder().command(commands).directory(workDir.toFile()).start();// 读取进程标准输出new Thread(() -> {try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {String line = null;while ((line = bufferedReader.readLine()) != null) {LOGGER.info(line);}} catch (IOException e) {}}).start();// 读取进程异常输出new Thread(() -> {try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {String line = null;while ((line = bufferedReader.readLine()) != null) {LOGGER.info(line);}} catch (IOException e) {}}).start();// 阻塞直到任务结束if (process.waitFor() != 0) {throw new RuntimeException("视频切片异常");}// 切出封面if (!screenShots(source, String.join(File.separator, destFolder, "poster.jpg"), config.getPoster())) {throw new RuntimeException("封面截取异常");}// 获取视频信息MediaInfo mediaInfo = getMediaInfo(source);if (mediaInfo == null) {throw new RuntimeException("获取媒体信息异常");}// 生成index.m3u8文件genIndex(String.join(File.separator, destFolder, "index.m3u8"), "ts/index.m3u8", mediaInfo.getFormat().getBitRate());// 删除keyInfo文件Files.delete(keyInfo);}/*** 获取视频文件的媒体信息* @param source* @return* @throws IOException* @throws InterruptedException*/public static MediaInfo getMediaInfo(String source) throws IOException, InterruptedException {List<String> commands = new ArrayList<>();commands.add("ffprobe");commands.add("-i");commands.add(source);commands.add("-show_format");commands.add("-show_streams");commands.add("-print_format");commands.add("json");Process process = new ProcessBuilder(commands).start();MediaInfo mediaInfo = null;try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {mediaInfo = new Gson().fromJson(bufferedReader, MediaInfo.class);} catch (IOException e) {e.printStackTrace();}if (process.waitFor() != 0) {return null;}return mediaInfo;}/*** 截取视频的指定时间帧,生成图片文件* @param source        源文件* @param file            图片文件* @param time            截图时间 HH:mm:ss.[SSS]* @throws IOException* @throws InterruptedException*/public static boolean screenShots(String source, String file, String time) throws IOException, InterruptedException {List<String> commands = new ArrayList<>();commands.add("ffmpeg");commands.add("-i");commands.add(source);commands.add("-ss");commands.add(time);commands.add("-y");commands.add("-q:v");commands.add("1");commands.add("-frames:v");commands.add("1");commands.add("-f");commands.add("image2");commands.add(file);Process process = new ProcessBuilder(commands).start();// 读取进程标准输出new Thread(() -> {try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {String line = null;while ((line = bufferedReader.readLine()) != null) {LOGGER.info(line);}} catch (IOException e) {}}).start();// 读取进程异常输出new Thread(() -> {try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {String line = null;while ((line = bufferedReader.readLine()) != null) {LOGGER.error(line);}} catch (IOException e) {}}).start();return process.waitFor() == 0;}}

11.转码成功返回m3u8文件的路径,放到页面input隐藏标签中

编码成功后执行回调函数,m3u8文件赋给_data变量如下图

使用$(#页面元素id).val(值),下图是把m3u8赋值给页面的input

12.最后页面form提交,保存视频转码后m3u8的路径。

相关文章:

大文件上传

上图就是大致的流程一、标题图片上传课程的标题图片Ajax发送请求到后端后端接收到图片使用IO流去保存图片&#xff0c;返回图片的信息对象JS回调函数接收对象通过$("元素id").val(值)&#xff0c;方式给页面form表达img标签src属性值&#xff0c;达到上传图片并回显二…...

Python每日一练(20230327)

目录 1. 最大矩形 &#x1f31f;&#x1f31f;&#x1f31f; 2. 反转链表 II &#x1f31f;&#x1f31f; 3. 单词接龙 II &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日…...

Centos7 升级内核到5.10mellanox 编译安装

升级5.10内核 #uname -r 重启后 进入新的内核 进入新的内核信息 直接查看是看不到gcc版本 5.10需要高版本gcc 才可以进行编译...

冯诺依曼,操作系统以及进程概念

文章目录一.冯诺依曼体系结构二.操作系统&#xff08;operator system&#xff09;三.系统调用和库函数四.进程1.进程控制块&#xff08;PCB&#xff09;2.查看进程3.系统相关的调用4.fork介绍&#xff08;并发引入&#xff09;五.总结一.冯诺依曼体系结构 计算机大体可以说是…...

7.网络爬虫—正则表达式详讲

7.网络爬虫—正则表达式详讲与实战Python 正则表达式re.match() 函数re.search方法re.match与re.search的区别re.compile 函数检索和替换检索&#xff1a;替换&#xff1a;findallre.finditerre.split正则表达式模式常见的字符类正则模式正则表达式模式量词正则表达式举例前言&…...

关于位运算的巧妙性:小乖,你真的明白吗?

一.位运算的概念什么是位运算&#xff1f;程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。位运算就是直接操作二进制数&#xff0c;那么有哪些种类的位运算呢&#xff1f;常见的运算符有与(&)、或(|)、异或(^)、…...

【Android车载系列】第5章 AOSP开发环境配置

1 硬件支持 建议空闲内存16G以上&#xff0c;同时硬盘400G以上 内存不够可以使用 Linux 的交换分区2 VMware Workstation安装 https://download3.vmware.com/software/wkst/file/VMware-workstation-full-16.1.1-17801498.exe2.1 Ubuntu镜像 http://mirrors.aliyun.com/ubun…...

个人时间管理网站—Git项目管理

&#x1f31f;所属专栏&#xff1a;献给榕榕&#x1f414;作者简介&#xff1a;rchjr——五带信管菜只因一枚&#x1f62e;前言&#xff1a;该专栏系为女友准备的&#xff0c;里面会不定时发一些讨好她的技术作品&#xff0c;感兴趣的小伙伴可以关注一下~&#x1f449;文章简介…...

2023最新ChatGPT整理的40道Java高级面试题

2023 年最火的就是 ChatGPT 了,很多同事使用他完成一些代码上的智能提示,也有人使用它发了财《「用ChatGPT年入百万!」各博主发布生财之道,网友:答辩搬运工》、《“躺着就能赚大钱”?ChatGPT火了,有人早就动起坏脑筋》等。 最近我也使用 ChatGPT 写技术文章了,比如:《…...

单机分布式一体化是什么?真的是数据库的未来吗,OceanBase或将开启新的里程碑

一. 数据 我们先说说数据这个东西&#xff0c;这段时间的ChatGPT在全世界的爆火说明了一件事&#xff0c;数据是有用的&#xff0c;并且大量的数据如果有一个合适的LLM大规模语言模型训练之后&#xff0c;可以很高程度的完成很多意想不到的事情。 我们大多数的时候的注意力只…...

100天精通Python丨基础知识篇 —— 03、Python基础知识扫盲(第一个Python程序,13个小知识点)

文章目录&#x1f41c; 1、Python 初体验Pycharm 第一个程序交互式编程第一个程序&#x1f41e; 2、Python 引号&#x1f414; 3、Python 注释&#x1f985; 4、Python 保留字符&#x1f42f; 5、Python 行和缩进&#x1f428; 6、Python 空行&#x1f439; 7、Python 输出&…...

springboot逍遥大药房管理系统

084-springboot逍遥大药房管理系统演示录像开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&a…...

ZYNQ中的GPIO与AXI GPIO

GPIO GPIO—一种外设&#xff0c;对器件进行观测和控制MIO—将来自PS外设和静态存储器接口的访问多路复用到PS引脚上处理器控制外设的方法—通过一组寄存器包括状态寄存器和控制寄存器&#xff0c;这些寄存器都是有地址的&#xff0c;通过这些寄存器的读写进行外设的控制sessi…...

接口导入功能

1.接口api export function import(param) { return fetch({ url: XXX.import, method: POST, headers: { Content-Type: multipart/form-data; }, data: param }) } 2.页面vue 和 js逻辑 <el-button :loading"disable&qu…...

网络安全知识点总结 期末总结

1、信息安全从总体上可以分成5个层次&#xff0c;密码技术 是信息安全中研究的关键点。 2、握手协议 用于客户机与服务器建立起安全连接之前交换一系列信息的安全信道。 3、仅设立防火墙系统&#xff0c;而没有 安全策略 &#xff0c;防火墙就形同虚设。 4、应用代理防火墙 …...

linux挂载远程目录

服务端操作 # 1、安装NFS程序 yum -y install nfs* rpcbind,在centos6以前自带的yum源中为portmap。 使用yum安装nfs时会下载依赖&#xff0c;因此只要下载nfs即可&#xff0c;无需再下载rpcbind. # 2、查看是否安装了nfs与rpcbind rpm -qa | grep nfs rpm -qa | grep rpc…...

ChatGPT—初识

ChatGPT初识 由于ChatGPT 注册相关的文章被平台限制了&#xff0c;所以有注册相关的问题可以私聊&#xff0c;或者可以代注册 Chat GPT是一款基于GPT模型的对话型AI模型&#xff0c;能够模拟真实的对话风格和行为方式&#xff0c;让人与AI的交互变得更加自然顺畅。下面将从Chat…...

【ArcGIS Pro二次开发】(18):地理处理工具类【Geoprocessing】补遗

ArcGIS Pro SDK 3.0中的Geoprocessing类是用于执行地理处理工具的核心类。地理处理工具是用于执行空间分析、数据转换、数据管理等任务的工具集&#xff0c;包括常见的空间分析工具、栅格处理工具、矢量处理工具、地图制图工具等。 之前有简单记录了下Geoprocessing工具的用法…...

国产芯片方案——红外测温体温计方案

红外测温体温计采用了热电堆式&#xff0c;利用塞贝克效应&#xff0c;将收集到的红外线光信号转化为电信号&#xff0c;再经过放大等处理&#xff0c;按内部的算法校正后再显示屏幕上输出具体温度值&#xff0c;能快速准确地测量人体体温。红外测温体温计广泛应用于医疗卫生、…...

详解ChatGPT的免费总结插件Glarity

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,科大讯飞比赛第三名,CCF比赛第四名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…...

RK3588平台开发系列讲解(NPU篇)NPU调试方法

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、日志等级二、NPU 支持查询设置项沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们一起来看一下NPU的调试方法。 一、日志等级 NPU 的运行库会根据开发板上的系统环境变量输出一些日志信息或者生成…...

基于微信小程序+爬虫制作一个表情包小程序

跟朋友聊天斗图失败气急败坏的我选择直接制作一个爬虫表情包小程序&#xff0c;从源头解决问题&#xff0c;从此再也不用担心在斗图中落入下风 精彩专栏持续更新↓↓↓ 微信小程序实战开发专栏 一、API1.1 项目创建1.2 图片爬虫帮助类1.3 测试窗体1.4 接口封装二、小程序2.1 项…...

TS常用数据类型(TypeScript常用数据类型,ts常用数据类型和js常用数据类型的区别)

简述&#xff1a;TS全称TypeScript&#xff0c;是一门弱类型的语言&#xff0c;可以理解为是 JavaScript 的扩展语法&#xff0c;因此我们可以在 ts 中继续写js代码&#xff0c;且不会报错&#xff0c;而且TypeScript 又叫做静态的JavaScript&#xff0c;可称为静态类型语言&am…...

关于Numpy的特殊符号@和矩阵运算

符号之谜 在Numpy中&#xff0c;看到了符号&#xff0c;但是无论是google搜索或者baidu搜索&#xff0c;由于符号是一个特殊字符&#xff0c;所以很难检索到答案。 其实很简单&#xff0c;他就是Numpy库中的一个操作符&#xff0c;在numpy库的说明中&#xff0c;落在numpy.mat…...

动态版通讯录——“C”

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰的内容是动态版通讯录啦&#xff0c;其实之前&#xff0c;我就已经写过静态版的通讯录了&#xff0c;只是存在着一些问题&#xff0c;具体细节可以详细看看我的静态版通讯录&#xff0c;好了&#xff0c;话不多说&…...

SpringBoot 将PDF转成图片或World

SpringBoot 将PDF转成图片或World 准备工作Apache PDFBox将PDF转成一张图片将PDF转成多张图片将PDF转成其他文件格式总结SpringBoot 是一款非常流行的 Java Web 开发框架,可以用来构建各种 Web 应用程序。在本篇博客中,我们将介绍如何使用 SpringBoot 将 PDF 转换成图片或其他…...

JavaScript中的for in和for of的区别(js的for循环)

简述&#xff1a;js中的for循环大家都知道&#xff0c;今天来分享下for in和for of在使用时区别和注意事项&#xff0c;顺便做个笔记&#xff1b; 测试数据 //数组const arr [1, 2, 3, 4, 5]//对象const obj {name: "小李",color: ["plum", "pink&q…...

C++的各种初始化

C的各种初始化 1.默认初始化 默认初始化是指定义变量时没有指定初值时进行的初始化操作。例如int a; Sales_data myData;等等。这些变量被定义了而不是仅仅被声明&#xff08;因为没有extern关键字修饰&#xff09;&#xff0c;而且没有显式的赋予初值。特别的&#xff0c;如…...

使用Python突破某网游游戏JS加密限制,进行逆向解密,实现自动登录

兄弟们天天看基础看腻了吧 今天来分享一下如何使用Python突破某网游游戏JS加密限制&#xff0c;进行逆向解密&#xff0c;实现自动登录。 逆向目标 目标&#xff1a;某 7 网游登录主页&#xff1a;aHR0cHM6Ly93d3cuMzcuY29tLw接口&#xff1a;aHR0cHM6Ly9teS4zNy5jb20vYXBpL…...

用CSS3画了一只猫

感觉我写得技术含量不高&#xff0c;全都是用绝对定位写的&#xff0c;一定会有更好的&#xff0c;代码量更少的做法吧 <!DOCTYPE html> <html> <head><title>Cute Cat</title><style type"text/css">*{box-sizing: border-box…...

住房和城乡建设厅网站青海省/今日军事新闻头条

typedef int ElemType; typedef struct Node { ElemType data; struct Node *prev; struct Node *next; }RingLink;以上是定义结构体。 以下是双向循环链表的实现 void RingLinkInit(RingLink *head) //初始化 { if (head NULL) exit(0); head->next head->prev …...

企业网站策划流程/成人短期电脑培训班学费

选择题在高考中属于保分题目&#xff0c;只有“选择题多拿分&#xff0c;高考才能得高分”&#xff0c;在平时的训练中&#xff0c;针对选择题要做到两个方面&#xff1a;一是练准确度&#xff1b;高考中遗憾的不是难题做不出来&#xff0c;而是简单题和中档题做错&#xff1b;…...

手机微信客户端网站建设/成都网站设计公司

ajax 毕竟是异步的 所以动态加载出来的数据 难免遇到 css 或者 js 失效的问题&#xff0c;所以要动态加载 css ji等文件了1.公共方法 load//动态加载 js /cssfunction loadjscssfile(filename, filetype) {if (filetype "js") { //判定文件类型var fileref documen…...

网站怎么做排名/百度推广怎么操作流程

什么是过滤器&#xff1f;有什么用&#xff1f;过滤器JavaWeb三大组件之一&#xff0c;它与Servlet很相似。不过滤器是用来拦截请求的&#xff0c;而不是处理请求的。过滤&#xff0c;顾名思义&#xff0c;就是留下我们想要的&#xff0c;丢掉我们不需要的。例如&#xff1a;某…...

wordpress网站插件下载/东莞seo优化排名推广

来源&#xff5c;华商韬略编辑&#xff5c;安小曼丁磊的变与不变。吴晓波说&#xff0c;他所见过的富人中&#xff0c;几乎没有一个是快乐的。仔细想后又改口了&#xff1a;哦&#xff0c;有一个&#xff0c;丁磊&#xff01;01表面不着急&#xff0c;暗中抓紧干2020年&#xf…...

win主机 wordpress静态/推广app佣金平台正规

刑法规定&#xff0c;公司、企业和其他单位的工作人员利用职务上的便利&#xff0c;非法侵占单位的财产&#xff0c;处五年以下有期徒刑或者拘役&#xff1b;情节严重的&#xff0c;可以并处五年以上有期徒刑。关于侵吞公司财产的会被判多少年的问题&#xff0c;合肥律师已经整…...