refactor(ForJdk17): 重构 CRC16_ARC 类并添加单元测试

-重构了 attachCRC16ARC、generateCRC16ARCForSend 和 verifyCRC16ARC 方法,使其支持 InputStream 和 OutputStream 参数
- 添加了 test12 和 test1单元测试方法来验证 CRC16_ARC 功能
-移除了 main 方法中的测试代码
This commit is contained in:
whai 2024-11-24 11:06:14 +08:00
parent f62c9fcd0a
commit 5c7eae4444
6 changed files with 363 additions and 18 deletions

View File

@ -1,8 +1,8 @@
package cn.whaifree.test; package cn.whaifree.test;
import java.io.FileInputStream; import org.junit.Test;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.*;
import java.util.Arrays; import java.util.Arrays;
/** /**
@ -55,26 +55,34 @@ public class CRC16_ARC {
public static void attachCRC16ARC(String sourceFilePath, String destinationFilePath) throws IOException { public static void attachCRC16ARC(String sourceFilePath, String destinationFilePath) throws IOException {
// 打开源文件并读取所有内容 // 打开源文件并读取所有内容
FileInputStream fis = new FileInputStream(sourceFilePath); FileInputStream fis = new FileInputStream(sourceFilePath);
byte[] data = fis.readAllBytes(); attachCRC16ARC(fis, new FileOutputStream(destinationFilePath));
fis.close(); }
public static void attachCRC16ARC(InputStream is, OutputStream os) throws IOException {
byte[] data = is.readAllBytes();
is.close();
// 计算源文件数据的CRC16ARC校验值 // 计算源文件数据的CRC16ARC校验值
int crcValue = calculateCRC16ARC(data); int crcValue = calculateCRC16ARC(data);
// 创建输出流准备写入目标文件
// 打开目标文件写入源文件数据和CRC校验值 // 打开目标文件写入源文件数据和CRC校验值
FileOutputStream fos = new FileOutputStream(destinationFilePath); os.write(data);
fos.write(data);
// 写入CRC的高字节 // 写入CRC的高字节
fos.write((crcValue & 0xFF00) >> 8); os.write((crcValue & 0xFF00) >> 8);
// 写入CRC的低字节 // 写入CRC的低字节
fos.write(crcValue & 0xFF); os.write(crcValue & 0xFF);
fos.close(); os.close();
} }
public static byte[] generateCRC16ARCForSend(String filePath) throws IOException { public static byte[] generateCRC16ARCForSend(String filePath) throws IOException {
FileInputStream fis = new FileInputStream(filePath); FileInputStream fis = new FileInputStream(filePath);
byte[] data = fis.readAllBytes(); return generateCRC16ARCForSend(fis);
fis.close(); }
public static byte[] generateCRC16ARCForSend(InputStream is) throws IOException {
byte[] data = is.readAllBytes();
is.close();
// 计算CRC16ARC校验值 // 计算CRC16ARC校验值
int crcValue = calculateCRC16ARC(data); int crcValue = calculateCRC16ARC(data);
@ -108,8 +116,12 @@ public class CRC16_ARC {
*/ */
public static boolean verifyCRC16ARC(String filePath) throws IOException { public static boolean verifyCRC16ARC(String filePath) throws IOException {
FileInputStream fis = new FileInputStream(filePath); FileInputStream fis = new FileInputStream(filePath);
byte[] data = fis.readAllBytes(); return verifyCRC16ARC(fis);
fis.close(); }
public static boolean verifyCRC16ARC(InputStream is) throws IOException {
byte[] data = is.readAllBytes();
is.close();
// 文件附带的CRC // 文件附带的CRC
int fileCRC = ((data[data.length - 2] & 0xFF) << 8) | (data[data.length - 1] & 0xFF); int fileCRC = ((data[data.length - 2] & 0xFF) << 8) | (data[data.length - 1] & 0xFF);
@ -120,18 +132,30 @@ public class CRC16_ARC {
return fileCRC == calculatedCRC; return fileCRC == calculatedCRC;
} }
@Test
public void test12() throws IOException, ClassNotFoundException {
byte[] bytes = {0x01, 0x02};
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
attachCRC16ARC(bis, bos);;
public static void main(String[] args) throws IOException, ClassNotFoundException { if (verifyCRC16ARC(new ByteArrayInputStream(bos.toByteArray()))) {
System.out.println("验证成功");
} else {
System.out.println("验证失败");
}
}
@Test
public void test1() throws IOException, ClassNotFoundException {
String filePath = "D:\\Downloads\\BFD-D42401883.pdf"; String filePath = "D:\\Downloads\\BFD-D42401883.pdf";
String destinationFilePath = "D:\\Downloads\\BFD-D42401883-1.pdf"; // 输出的 String destinationFilePath = "D:\\Downloads\\BFD-D42401883-1.pdf"; // 输出的
attachCRC16ARC(filePath, destinationFilePath); attachCRC16ARC(filePath, destinationFilePath);
if (verifyCRC16ARC(destinationFilePath)) { if (verifyCRC16ARC(destinationFilePath)) {
System.out.println("验证成功"); System.out.println("验证成功");
}else { } else {
System.out.println("验证失败"); System.out.println("验证失败");
} }
@ -139,7 +163,7 @@ public class CRC16_ARC {
byte[] bytes = generateCRC16ARCForSend(filePath); // 生成附带CRC的完整文件 byte[] bytes = generateCRC16ARCForSend(filePath); // 生成附带CRC的完整文件
if (verifyCRC16ARCByBytes(bytes)) { // 验证 if (verifyCRC16ARCByBytes(bytes)) { // 验证
System.out.println("验证成功"); System.out.println("验证成功");
}else { } else {
System.out.println("验证失败"); System.out.println("验证失败");
} }

View File

@ -0,0 +1,58 @@
package cn.whaifree.springdemo.controller.TS.HTTP;
import cn.whaifree.springdemo.controller.TS.common.ProcessStrategy;
import cn.whaifree.springdemo.controller.TS.common.ProcessTarget;
import cn.whaifree.springdemo.controller.TS.common.TargetDown;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/11/22 21:21
* @注释
*/
@RestController
public class QBController {
@RequestMapping("/TargetDown")
public void targetDown(String msg) {
ProcessStrategy processStrategy = ProcessTarget.getProcessStrategy(ProcessTarget.TARGET_DOWN);
processStrategy.process(msg);
}
public void compressImage(InputStream inputStream, float quality, String fileFullName) {
try {
BufferedImage read = ImageIO.read(inputStream);
File out = new File(fileFullName);
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
OutputStream os = new java.io.FileOutputStream(out);
JPEGImageWriteParam param = new JPEGImageWriteParam(null);
param.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality); // 压缩质量
writer.setOutput(ImageIO.createImageOutputStream(os));
writer.write(null, new javax.imageio.IIOImage(read, null, null), param);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@RequestMapping("/TargetFind")
public void targetFind(String msg) {
ProcessStrategy processStrategy = ProcessTarget.getProcessStrategy(ProcessTarget.TARGET_FIND);
processStrategy.process(msg);
}
}

View File

@ -0,0 +1,55 @@
package cn.whaifree.springdemo.controller.TS.SSE;
import cn.hutool.core.util.StrUtil;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/22 21:44
* @注释
*/
@RestController
public class SSEEmitterDemo {
Map<String, SseEmitter> sseEmitterMap = new ConcurrentHashMap<>();
/**
* 签约
* @param key
* @return
*/
@GetMapping(value = "/sseStart", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter sse(String key) {
System.out.println(key);
if (!sseEmitterMap.containsKey(key)) {
SseEmitter sseEmitter = new SseEmitter();
sseEmitterMap.put(key, sseEmitter);
}
return sseEmitterMap.get(key);
}
@PostMapping("sendSSE")
public void send(String key, String message) {
if (sseEmitterMap.containsKey(key)) {
SseEmitter sseEmitter = sseEmitterMap.get(key);
try {
System.out.println(StrUtil.format("send message to {}:{}", key, message));
sseEmitter.send(message);
} catch (IOException e) {
e.printStackTrace();
}
}else {
throw new IllegalArgumentException("No such key");
}
}
}

View File

@ -0,0 +1,7 @@
package cn.whaifree.springdemo.controller.TS.common;
public interface ProcessStrategy {
void process(byte[] frame);
void process(Object o);
}

View File

@ -0,0 +1,47 @@
package cn.whaifree.springdemo.controller.TS.common;
import cn.hutool.extra.spring.SpringUtil;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;
import java.util.HashMap;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/11/22 20:48
* @注释
*/
@Component
public class ProcessTarget {
public static final int TARGET_FIND = processToInt(new byte[]{0x00, 0x00, 0x00, 0x00});
public static final int TARGET_DOWN = processToInt(new byte[]{0x00, 0x00, 0x00, 0x01});
static HashMap<Integer, ProcessStrategy> processStrategyHashMap = new HashMap<>();
@PostConstruct
public void init() {
processStrategyHashMap.put(TARGET_FIND, SpringUtil.getBean(TargetStorage.class));
processStrategyHashMap.put(TARGET_DOWN, SpringUtil.getBean(TargetDown.class));
}
private static int processToInt(byte[] heads) {
if (heads.length < 4) {
return -1;
}
// 获取前4个byte转为int
return (heads[0] & 0xFF) << 24 | (heads[1] & 0xFF) << 16 | (heads[2] & 0xFF) << 8 | (heads[3] & 0xFF);
}
public static ProcessStrategy getProcessStrategy(byte[] heads) {
return processStrategyHashMap.get(processToInt(heads));
}
public static ProcessStrategy getProcessStrategy(int code) {
return processStrategyHashMap.get(code);
}
}

View File

@ -0,0 +1,154 @@
package cn.whaifree.springdemo.controller.workBook.export;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.poi.excel.WorkbookUtil;
import cn.whaifree.springdemo.controller.workBook.WorkBookController;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Data;
import lombok.Setter;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/11/20 16:35
* @注释
*/
@RestController
@RequestMapping("/workBookAuto")
public class ExportAutoController {
@GetMapping(value = "/exportUser1")
public void export1(HttpServletResponse response) {
try (OutputStream out = response.getOutputStream()) {
List<User> userList = getUserList();
Workbook query = WorkBookResponseUtils.getWorkBook(userList, User.class, response, "导出成员工时");
query.write(out);
out.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@GetMapping(value = "/exportUser")
public void export(HttpServletResponse response) throws UnsupportedEncodingException {
// WorkBook
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder
.encode("导出成员工时.xlsx", "UTF-8"));
response.setContentType("application/vnd.ms-excel;charset=utf-8");
try (
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/project_member_workHours.xlsx");
OutputStream out = response.getOutputStream()
) {
Workbook query = query(inputStream);
query.write(out);
out.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public Workbook query(InputStream inputStream) {
Workbook workbook = WorkbookUtil.createSXSSFBook(inputStream);
Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
List<User> userList = getUserList();
for (int i = 0; i < userList.size(); i++) {
Row row = sheet.createRow(i + 1);
Cell cell = row.createCell(0);
cell.setCellValue(userList.get(i).getNickName());
cell = row.createCell(1);
cell.setCellValue(userList.get(i).getFullName());
cell = row.createCell(2);
cell.setCellValue(userList.get(i).getDepartment());
}
return workbook;
}
public Workbook query2(InputStream inputStream) {
Workbook workbook = WorkbookUtil.createSXSSFBook(inputStream);
Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
List<User2> userList = getUser2List();
for (int i = 0; i < userList.size(); i++) {
Row row = sheet.createRow(i + 1);
Cell cell = row.createCell(0);
cell.setCellValue(userList.get(i).getNickName());
cell = row.createCell(1);
cell.setCellValue(userList.get(i).getFullName());
cell = row.createCell(2);
cell.setCellValue(userList.get(i).getDepartment());
}
return workbook;
}
@Data
@Setter
static class User {
private String nickName;
private String fullName;
private String department;
}
@Data
@Setter
static class User2 {
private String nickName;
private String fullName;
private String department;
}
public static List<User> getUserList() {
List<User> userList = new ArrayList<>();
for (int i = 0; i < 30; i++) {
User user = new User();
user.setNickName("张三" + i);
user.setDepartment("研发部");
user.setFullName("张三" + i);
userList.add(user);
}
return userList;
}
public static List<User2> getUser2List() {
List<User2> userList = new ArrayList<>();
for (int i = 0; i < 30; i++) {
User2 user = new User2();
user.setNickName("张三" + i);
user.setDepartment("研发部");
user.setFullName("张三" + i);
userList.add(user);
}
return userList;
}
}