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

java pdf,word,ppt转图片

pom.xml

<?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.7.8</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.test</groupId><artifactId>local-service</artifactId><version>0.0.1-SNAPSHOT</version><name>local-service</name><description>local-service</description><properties><java.version>8</java.version><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></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-websocket</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.13.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.32</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.24.0</version></dependency><!--PDF操作工具包--><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox-app</artifactId><version>2.0.16</version></dependency><!-- word操作工具包--><dependency><groupId>words</groupId><artifactId>aspose-words</artifactId><version>1.0.0</version></dependency><!-- ppt操作工具包--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.xmlgraphics</groupId><artifactId>batik-bridge</artifactId><version>1.9.1</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
文件转换统一工具类 FileConvertUtil.java

调用 FileConvertUtil.convert2Images(filePath)即可输出图片信息

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.python.jline.internal.Log;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.Base64Utils;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;/*** @author yangguang* @date 2023年11月01日 17:01*/
@Slf4j
public class FileConvertUtil {private static Map<String, BiFunction<String,String, List<ImageInfo>>> convertFactory = new HashMap<>();static {convertFactory.put("ppt", PPTUtil::ppt2image);convertFactory.put("pptx", PPTUtil::pptx2image);convertFactory.put("doc", WordUtil::word2image);convertFactory.put("docx", WordUtil::word2image);convertFactory.put("pdf", PdfUtil::pdf2image);}public static List<ImageInfo> convert2Images(String filePath) {File file = new File(filePath);String name = file.getName().substring(0,file.getName().lastIndexOf("."));String targetDir = file.getParentFile().getAbsolutePath()+File.separator+name;if(new File(targetDir).exists()){return Arrays.stream(new File(targetDir).listFiles()).map(File::getAbsolutePath).sorted((name1,name2)->Integer.compare(getFileIndex(name1),getFileIndex(name2))).map(FileConvertUtil::file2ImageInfo).collect(Collectors.toList());}else{new File(targetDir).mkdirs();}String suffix = filePath.substring(filePath.lastIndexOf(".") + 1);List<ImageInfo> list = Optional.ofNullable(convertFactory.get(suffix)).map(f -> f.apply(filePath,targetDir)).orElseThrow(() -> new CustomException("不支持得文件类型"));return list;}public static List<String> convert2ImagesBase64(String filePath) {return convert2Images(filePath).stream().map(ImageInfo::getPath).map(FileConvertUtil::base64Encoding).collect(Collectors.toList());}public static void clearWorkPath(File dir) {if (dir == null) {File file = new File(Constants.TEMP_PATH);for (File f : file.listFiles()) {clearWorkPath(f);}} else if (dir.isDirectory()) {for (File file : dir.listFiles()) {clearWorkPath(file);}dir.delete();} else {dir.delete();}}private static String base64Encoding(String imagePath) {InputStream in = null;try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {//建一个空的字节数组byte[] result = null;in = new FileInputStream(imagePath);byte[] buf = new byte[1024];//用来定义一个准备接收图片总长度的局部变量int len;//将流的内容读取到buf内存中while ((len = in.read(buf)) > 0) {//将buf内存中的内容从0开始到总长度输出出去out.write(buf, 0, len);}//将out中的流内容拷贝到一开始定义的字节数组中result = out.toByteArray();//通过util包中的Base64类对字节数组进行base64编码String base64 = Base64.getEncoder().encodeToString(result);return "data:Image/" + "PNG" + ";base64," + base64;} catch (Exception e) {log.error("image to base64 error",e);throw new CustomException("image to base64 error");}}private static int getFileIndex(String filePath){String fileName = new File(filePath).getName();return Integer.parseInt(fileName.substring(0,fileName.lastIndexOf(".")));}private static ImageInfo file2ImageInfo(String filePath) {ImageInfo.ImageInfoBuilder builder = ImageInfo.builder();BufferedImage img = null;File f = null;try {f = new File(filePath);img = ImageIO.read(f);return builder.width(img.getWidth()).height(img.getHeight()).path(filePath).build();}catch (IOException e) {log.error("读取文件失败",e);throw new CustomException("读取文件失败");}}}

图片对象ImageInfo.java

@Data
@Builder
public class ImageInfo {private String path;private Integer width;private Integer height;}
常量文件输出路径Constants.java
/*** @author yangguang* @date 2023年11月01日 15:35*/
public interface Constants {String CONF_PATH = System.getProperty("user.dir") + File.separator + "conf";String TEMP_PATH = System.getProperty("user.dir") + File.separator + "temp";
}

WordUtil.java

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.IntStream;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import com.aspose.words.Document;
import com.aspose.words.ImageSaveOptions;
import com.aspose.words.SaveFormat;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.tomcat.util.http.fileupload.IOUtils;@Slf4j
public class WordUtil {/*** 验证aspose.word组件是否授权:无授权的文件有水印标记* 需要使用(aspose-words-15.8.0-jdk16.jar),版本要对应。无水印* @return*/private static boolean isWordLicense(){boolean result = false;try {String s = "<License><Data><Products><Product>Aspose.Total for Java</Product><Product>Aspose.Words for Java</Product></Products><EditionType>Enterprise</EditionType><SubscriptionExpiry>20991231</SubscriptionExpiry><LicenseExpiry>20991231</LicenseExpiry><SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber></Data><Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature></License>";ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());com.aspose.words.License license = new com.aspose.words.License();license.setLicense(inputStream);result = true;} catch (Exception e) {e.printStackTrace();}return result;}//outputStream转inputStreamprivate static ByteArrayInputStream parse(OutputStream out) throws Exception{ByteArrayOutputStream baos = new ByteArrayOutputStream();baos = (ByteArrayOutputStream) out;ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());return swapStream;}/*** word和txt文件转换图片* @param inputStream* @param* @return* @throws Exception*/private static List<BufferedImage> wordToImg(InputStream inputStream) throws Exception{if (!isWordLicense()){return null;}try {Date start = new Date();Document doc = new Document(inputStream);ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG);options.setPrettyFormat(true);options.setUseAntiAliasing(true);options.setUseHighQualityRendering(true);int pageCount = doc.getPageCount();//生成前pageCount张,这可以限制输出长图时的页数(方法入参可以传值pageNum)/*if (pageCount > pageNum) {pageCount = pageNum;}*/List<BufferedImage> imageList = new ArrayList<BufferedImage>();for (int i = 0; i < pageCount; i++){OutputStream output = new ByteArrayOutputStream();options.setPageIndex(i);doc.save(output, options);ImageInputStream imageInputStream = javax.imageio.ImageIO.createImageInputStream(parse(output));imageList.add(javax.imageio.ImageIO.read(imageInputStream));}List<BufferedImage> imageList2 = new ArrayList<BufferedImage>();//这个重新生成新的图片是因为直接输出的图片底色为红色for(int j=0; j<imageList.size(); j++){// 生成新图片BufferedImage destImage = imageList.get(j);int w1 = destImage.getWidth();int h1 = destImage.getHeight();destImage = new BufferedImage(w1, h1, BufferedImage.TYPE_INT_RGB);Graphics2D g2 = (Graphics2D) destImage.getGraphics();g2.setBackground(Color.LIGHT_GRAY);g2.clearRect(0, 0, w1, h1);g2.setPaint(Color.RED);// 从图片中读取RGBint[] ImageArrayOne = new int[w1 * h1];ImageArrayOne = imageList.get(j).getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中destImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGBimageList2.add(destImage);}Date end = new Date();long l=end.getTime()-start.getTime();long hour= l / (1000 * 60 * 60);long min=  (l-hour*(1000 * 60 * 60 ))/(1000* 60);long s= (l-hour*(1000 * 60 * 60 )-min*1000*60)/(1000);long ss= (l-hour*(1000 * 60 * 60 )-min*1000*60 -s*1000)/(1000/60);System.out.println("word转图片时间:"+min+"分"+s+"秒" + ss + "毫秒");//hour+"小时"+return imageList2;} catch (Exception e) {e.printStackTrace();throw e;}}/*** 合并任数量的图片成一张图片* @param isHorizontal true代表水平合并,fasle代表垂直合并* @param imgs 待合并的图片数组* @return* @throws IOException*/public static BufferedImage mergeImage(boolean isHorizontal, List<BufferedImage> imgs) throws IOException{// 生成新图片BufferedImage destImage = null;// 计算新图片的长和高int allw = 0, allh = 0, allwMax = 0, allhMax = 0;// 获取总长、总宽、最长、最宽for (int i = 0; i < imgs.size(); i++){BufferedImage img = imgs.get(i);allw += img.getWidth();if (imgs.size() != i + 1){allh += img.getHeight() + 5;} else {allh += img.getHeight();}if (img.getWidth() > allwMax){allwMax = img.getWidth();}if (img.getHeight() > allhMax){allhMax = img.getHeight();}}// 创建新图片if (isHorizontal){destImage = new BufferedImage(allw, allhMax, BufferedImage.TYPE_INT_RGB);} else {destImage = new BufferedImage(allwMax, allh, BufferedImage.TYPE_INT_RGB);}Graphics2D g2 = (Graphics2D) destImage.getGraphics();g2.setBackground(Color.LIGHT_GRAY);g2.clearRect(0, 0, allw, allh);g2.setPaint(Color.RED);// 合并所有子图片到新图片int wx = 0, wy = 0;for (int i = 0; i < imgs.size(); i++){BufferedImage img = imgs.get(i);int w1 = img.getWidth();int h1 = img.getHeight();// 从图片中读取RGBint[] ImageArrayOne = new int[w1 * h1];ImageArrayOne = img.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中if (isHorizontal) { // 水平方向合并destImage.setRGB(wx, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB} else { // 垂直方向合并destImage.setRGB(0, wy, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB}wx += w1;wy += h1 + 5;}return destImage;}public static List<ImageInfo> word2image(String wordPath,String targetDir){List<ImageInfo> list = Lists.newArrayList();File file = new File(wordPath);InputStream inStream =null;try {inStream = new FileInputStream(file);List<BufferedImage> wordToImg = wordToImg(inStream);IntStream.range(0,wordToImg.size()).forEach(i->{//可以保存图片(每页保存为一张)try {String filePath = (targetDir==null?Constants.TEMP_PATH:targetDir)+File.separator+ i +".png";BufferedImage image = wordToImg.get(i);ImageInfo imageInfo = ImageInfo.builder().width(image.getWidth()).height(image.getHeight()).path(filePath).build();ImageIO.write(image, "jpg", new File(filePath)); //将其保存在C:/imageSort/targetPIC/下synchronized (list){list.add(imageInfo);}}catch (Exception e){log.error("word2pdf error 212",e);}});}catch (Exception e){log.error("word2pdf error",e);}finally {IOUtils.closeQuietly(inStream);}return list;}// 测试工具类public static void main(String[] args){String path = "E:\\网页\\test.docx";new WordUtil().word2image(path,null);}}

PPTUtil.java

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;/*** @author yangguang* @date 2023年11月01日 16:11*/
@Slf4j
public class PPTUtil {private final static double IMAGE_SCALE = 8;public static List<ImageInfo> ppt2image(String pptPath, String targetDir){List<ImageInfo> list = Lists.newArrayList();InputStream is = null;HSLFSlideShow ppt = null;try {File file = new File(pptPath);is = new FileInputStream(file);ppt =new HSLFSlideShow(is);Dimension pgSize = ppt.getPageSize();int i=0;for (HSLFSlide slide : ppt.getSlides()) {ImageInfo imageInfo = toPNG(targetDir,pgSize.width, pgSize.height, slide,i);list.add(imageInfo);i++;}} catch (IOException e) {log.error("ppt转换图片失败,{}", e.getMessage());throw new RuntimeException("ppt转换图片失败" + e.getMessage());} finally {try {if (is != null) {is.close();}} catch (IOException e) {e.printStackTrace();}try {if (ppt != null) {ppt.close();}} catch (IOException e) {e.printStackTrace();}}return list;}public static List<ImageInfo> pptx2image(String pptPath,String targetDir){InputStream is = null;XMLSlideShow ppt = null;List<ImageInfo> list = Lists.newArrayList();try {is = new FileInputStream(pptPath);ppt = new XMLSlideShow(is);Dimension pgSize = ppt.getPageSize();int i=0;for (XSLFSlide slide : ppt.getSlides()) {ImageInfo imageInfo = toPNG(targetDir,pgSize.width, pgSize.height, slide,i);list.add(imageInfo);i++;}} catch (IOException e) {log.error("pptx转换图片失败,{}", e.getMessage());throw new RuntimeException("pptx转换图片失败" + e.getMessage());} finally {try {if (is != null) {is.close();}} catch (IOException e) {e.printStackTrace();}try {if (ppt != null) {ppt.close();}} catch (IOException e) {e.printStackTrace();}}return list;}private static ImageInfo toPNG(String targetDir,int pgWidth, int pgHeight, Slide slide,int i) throws IOException {int imageWidth = (int) Math.floor(IMAGE_SCALE * pgWidth);int imageHeight = (int) Math.floor(IMAGE_SCALE * pgHeight);BufferedImage img = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);Graphics2D graphics = img.createGraphics();graphics.setPaint(Color.white);graphics.fill(new Rectangle2D.Float(0, 0, pgWidth, pgHeight));graphics.scale(IMAGE_SCALE, IMAGE_SCALE);slide.draw(graphics);// save the outputString filePath = (targetDir==null?Constants.TEMP_PATH:targetDir)+ File.separator+ i +".png";ImageInfo imageInfo = ImageInfo.builder().width(img.getWidth()).height(img.getHeight()).path(filePath).build();ImageIO.write(img, "jpg", new File(filePath));return imageInfo;}public static void main(String[] args) {new PPTUtil().ppt2image("E:\\网页test.ppt",null);}
}

PdfUtil.java

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.stereotype.Component;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.stream.IntStream;/*** @author yangguang* @date 2022年12月20日 9:56*/
@Component
@Slf4j
public class PdfUtil {private static ImageInfo pdftoimageByNum(PDFRenderer renderer, Integer pageNum, String imagePath)throws IOException{BufferedImage image = renderer.renderImageWithDPI(pageNum-1, 296);//image = FileUtil.bufferedImage2Transparent(image);//          BufferedImage image = renderer.renderImage(i, 2.5f);File file1 = new File(imagePath);if(!file1.getParentFile().exists()){file1.getParentFile().mkdirs();}ImageInfo imageInfo = ImageInfo.builder().width(image.getWidth()).height(image.getHeight()).path(imagePath).build();ImageIO.write(image, "PNG", new File(imagePath));return imageInfo;}private static String getFileName(String filepath) {String fileName;filepath = filepath.replaceAll("\\\\",File.separator);if(filepath.contains(File.separator)){fileName = filepath.substring(filepath.lastIndexOf(File.separator) + 1);}else{fileName = filepath;}if(!fileName.endsWith(".pdf")){throw new CustomException("文件格式不正确");}return fileName.substring(0,fileName.lastIndexOf("."));}public static List<ImageInfo> pdf2image(String pdfPath,String targetDir){List<ImageInfo> list = Lists.newArrayList();File file = new File(pdfPath);PDDocument doc=null;try {doc = PDDocument.load(file);PDFRenderer renderer = new PDFRenderer(doc);int pageCount = doc.getNumberOfPages();IntStream.range(0,pageCount).forEach(i->{try {String imagePath = (targetDir==null?Constants.TEMP_PATH:targetDir)+File.separator+ i + ".png";ImageInfo imageInfo = pdftoimageByNum(renderer, i + 1, imagePath);synchronized (list){list.add(imageInfo);}}catch (Exception e){log.error("转换图片失败",e);}});} catch (IOException e) {log.error("转换失败,io异常",e);throw new CustomException("转换失败,io异常");}finally {try {doc.close();} catch (Exception e) {log.error("io异常",e);}}return list;}public static void main(String[] args){List<ImageInfo> a = new PdfUtil().pdf2image("C:\\test.pdf",null);System.out.println(a);}
}

相关文章:

java pdf,word,ppt转图片

pom.xml <?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…...

map set

目录 一、关联式容器 二、键值对 三、树形结构的关联式容器 3.1 set 3.1.1 set的介绍 3.1.2 set的使用 3.2 multiset 3.2.1 multiset的介绍 3.2.2 multiset的使用 3.3 map 3.3.1 map的介绍 3.3.2 map的使用 …...

Fourier分析导论——第3章——Fourier级数的收敛性(E.M. Stein R. Shakarchi)

第 3 章 Fourier级数的收敛性(Convergence of Fourier Series) The sine and cosine series, by which one can represent an arbitrary function in a given interval, enjoy among other remarkable properties that of being convergent. This property did not escape…...

解决ruoyi-vue部署到域名子路径静态资源404

参考ruoyi前端手册...

游戏引擎中为什么要用四元数表示旋转而不用欧拉角旋转?

个人观点&#xff0c;仅供参考&#xff0c;如有错误可太刺激了 四元数的简单概念和使用 欧拉角通常用于表示一个物体的旋转状态&#xff0c;而不是表示旋转过程。 欧拉角描述的是物体相对于某个参考坐标系的朝向或旋转状态&#xff0c;通常以不同的轴&#xff08;例如&#x…...

E-Office(泛微OA)前台任意文件读取漏洞复现

简介 泛微E-Office是一款企业级的全流程办公自动化软件&#xff0c;它包括协同办公、文档管理、知识管理、工作流管理等多个模块&#xff0c;涵盖了企业日常工作中的各个环节。在该产品前台登录页存在文件读取漏洞。 officeserver.php文件存在任意文件读取漏洞&#xff0c;通…...

前端小案例 | 喵喵大王立大功 | 一个带便利贴功能的todolist面板

文章目录 &#x1f4da;html&#x1f4da;css&#x1f4da;js&#x1f407;stickynote.js&#x1f407;todolist.js&#x1f407;clock.js &#x1f4da;html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><m…...

算法训练营第十一天 | 20. 有效的括号、 1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

目录&#xff1a; 力扣 20. 有效的括号力扣 1047. 删除字符串中的所有相邻重复项力扣 150. 逆波兰表达式求值 问题一、 20. 有效的括号 题目链接&#xff1a;20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 思路分析&#xff1a; 很多朋友刚开始接触这一类题的时候…...

Python unittest单元测试框架 TestSuite测试套件

TestSuite 测试套件简介 对一个功能的验证往往是需要很多多测试用例&#xff0c;可以把测试用例集合在一起执行&#xff0c;这就产生了测试套件TestSuite 的概念&#xff0c;它是用来组装单个测试用例&#xff0c;规定用例的执行的顺序&#xff0c;而且TestSuite也可以嵌套Tes…...

FSB逮捕为乌克兰网络部队工作的俄罗斯黑客

导语 近日&#xff0c;俄罗斯联邦安全局&#xff08;FSB&#xff09;逮捕了两名涉嫌协助乌克兰网络部队对俄罗斯重要基础设施目标进行网络攻击的个人。这起事件引起了广泛关注&#xff0c;涉及到了网络安全和国际关系等多个领域。本文将为您详细介绍这一事件的背景和最新进展。…...

【PC电脑windows-学习样例tusb_serial_device-ESP32的USB模拟串口程序+VScode建立工程+usb组件添加+-基础样例学习】

【PC电脑windows-学习样例tusb_serial_device-ESP32的USB模拟串口程序-基础样例学习】 1、概述2、实验环境3-1、 物品说明3-2、所遇问题&#xff1a;ESP32 cannot open source file "tinyusb.h"或者“tinyusb.h:No such file or directory ....”3-3、解决问题&#…...

LeetCode75——Day26

文章目录 一、题目二、题解 一、题目 394. Decode String Given an encoded string, return its decoded string. The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guar…...

面试算法53:二叉搜索树的下一个节点

题目 给定一棵二叉搜索树和它的一个节点p&#xff0c;请找出按中序遍历的顺序该节点p的下一个节点。假设二叉搜索树中节点的值都是唯一的。例如&#xff0c;在图8.9的二叉搜索树中&#xff0c;节点8的下一个节点是节点9&#xff0c;节点11的下一个节点是null。 分析&#xf…...

2023SHCTF web方向wp

1.ezphp 看一眼&#xff0c;你大爷&#xff0c;啥玩意都给我过滤完了。 还好下面有preg_replace()/e&#xff0c;会把replacement当作php语句执行 传参pattern.*&#xff0c; .*表示任意字符&#xff0c;code{${phpinfo()}} &#xff0c;为什么这样写&#xff0c;因为,print_…...

从物理磁盘到数据库 —— 存储IO链路访问图

原图来自&#xff1a;数据库IO链路访问图 – OracleBlog 由于很复杂&#xff0c;为了加深理解自己重新画了一次&#xff0c;另外参考其他文档补充了各部分的插图和介绍。 一、 存储服务器 1. 物理磁盘 外层的壳子称为硬盘笼 cage 2. chunklet Chunklet 是一个虚拟概念而不是实…...

基于java+springboot+vue在线选课系统

项目介绍 本系统结合计算机系统的结构、概念、模型、原理、方法&#xff0c;在计算机各种优势的情况下&#xff0c;采用JAVA语言&#xff0c;结合SpringBoot框架与Vue框架以及MYSQL数据库设计并实现的。员工管理系统主要包括个人中心、课程管理、专业管理、院系信息管理、学生…...

GO学习之 同步操作sync包

GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Htt…...

NUUO网络摄像头(NVR)RCE漏洞复现

简介 NUUO Network Video Recorder&#xff08;NVR&#xff09;是中国台湾NUUO公司的一款网络视频记录器。 NUUO NVR视频存储管理设备的__debugging_center_utils___.php文件存在未授权远程命令执行漏洞&#xff0c;攻击者可在没有任何权限的情况下通过log参数执行任意命令。…...

一款快速获取目标网站关键信息的工具

1.摘要 今天要介绍的这款工具是一个快速收集网站信息的开源脚本, 采用Python语言编写, 该工具可以快速收集网站的页面标题、网站上次更新日期、DNS信息、子域、防火墙名称、网站使用的技术栈、证书等信息, 默认支持对验证码和JavaScript内容执行绕过操作。 2.工具安装使用 使…...

将GC编程语言引入WebAssembly的新方法

本文讨论了一种名为 WasmGC 的新方法&#xff0c;用于将垃圾收集编程语言有效地引入 WebAssembly。 WasmGC 定义了新的 GC 类型&#xff0c;例如结构和数组&#xff0c;与之前编译为线性内存的方法 (WasmMVP) 相比&#xff0c;它们可以实现更好的优化&#xff1a; 在编译时和…...

别再死记硬背了!用一张图+一个案例彻底搞懂PROFIBUS-DP的令牌环与主从通信

工业现场通信革命&#xff1a;从零图解PROFIBUS-DP令牌环与主从机制 第一次接触PROFIBUS-DP协议文档时&#xff0c;那些晦涩的术语和抽象的状态转换图让我在调试现场设备时屡屡碰壁。直到某天亲眼目睹PLC通过一串神秘的数据包精准控制阀门阵列&#xff0c;才意识到这套诞生于上…...

从IP到SoC:构建可重用验证环境的核心架构与实战

1. 项目概述&#xff1a;从IP到SoC&#xff0c;验证重用的价值与挑战在芯片设计这个行当里摸爬滚打十几年&#xff0c;最深的感触之一就是&#xff1a;验证&#xff0c;永远是那个最“烧钱”也最“烧时间”的环节。我们常开玩笑说&#xff0c;一个SoC项目&#xff0c;设计工程师…...

W5500 TCP客户端开发避坑指南:从寄存器配置到稳定通信的5个关键步骤

W5500 TCP客户端开发避坑指南&#xff1a;从寄存器配置到稳定通信的5个关键步骤 在嵌入式网络通信领域&#xff0c;W5500作为一款硬件集成TCP/IP协议栈的以太网控制器&#xff0c;因其易用性和稳定性备受开发者青睐。然而&#xff0c;当项目从实验室demo转向实际部署时&#xf…...

初次使用Taotoken完成模型调用从注册到收到响应的全过程记录

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 初次使用Taotoken完成模型调用从注册到收到响应的全过程记录 作为一名开发者&#xff0c;当需要将大模型能力集成到自己的项目中时…...

STM32图像识别实战:从传统CV到TinyML的边缘AI部署

1. 项目概述&#xff1a;当STM32遇上图像识别在嵌入式开发领域&#xff0c;STM32系列微控制器因其出色的性能、丰富的外设和极高的性价比&#xff0c;早已成为工程师和爱好者的“瑞士军刀”。从简单的LED闪烁到复杂的电机控制、通信协议栈&#xff0c;STM32几乎无所不能。但提到…...

EMD vs NEMD:分子动力学算热导率,新手到底该选哪个?

EMD与NEMD方法实战指南&#xff1a;如何为你的热导率计算选择最佳方案 在纳米材料和新型功能材料的研究中&#xff0c;热导率的精确计算是理解材料热输运性能的关键。面对平衡态分子动力学(EMD)和非平衡态分子动力学(NEMD)两种主流方法&#xff0c;许多研究者常常陷入选择困境。…...

保姆级教程:用Sen2Cor批量处理Sentinel-2 L1C到L2A(Win/Linux通用,附避坑清单)

遥感数据处理实战&#xff1a;Sen2Cor高效批量处理Sentinel-2 L1C至L2A全流程指南 当面对数百景Sentinel-2 L1C数据需要转换为L2A级别时&#xff0c;手动逐景处理不仅效率低下&#xff0c;还容易因操作失误导致数据不一致。本文将分享一套经过实际项目验证的批处理方案&#xf…...

别再焊错线了!51单片机+L298N驱动小车底盘,保姆级接线避坑指南

51单片机L298N驱动小车底盘&#xff1a;从零避坑到一次点亮 当你第一次把51单片机、L298N电机驱动模块、红外传感器和电源组装在一起时&#xff0c;是否曾被那些密密麻麻的杜邦线弄得晕头转向&#xff1f;每个初学者都可能经历过接错线导致芯片冒烟的惨痛教训。本文将用实战经验…...

别再死记命令了!用ENSP模拟企业网,手把手教你配置VRRP+MSTP实现网关和链路双备份

企业网络高可用实战&#xff1a;用ENSP构建VRRPMSTP双冗余架构 刚接触企业网络设计的工程师常陷入一个误区&#xff1a;把网络设备配置等同于命令记忆。我曾见过一位学员能完整背诵VRRP的配置指令&#xff0c;却在真实网络故障时手足无措——因为他从未理解这些命令背后的网络逻…...

小白程序员必看:收藏这份AI大模型学习指南,抢占高薪新赛道!

文章指出&#xff0c;随着AI技术的飞速发展&#xff0c;传统后端开发面临挑战&#xff0c;而懂AI的复合型人才成为稀缺资源。学校教育与企业需求存在错位&#xff0c;导致大学生毕业时所学与企业所需不符。AI智能应用开发、大模型开发等方向成为高薪热门领域&#xff0c;懂AI的…...