批次读取数据,不再一次一次读取

将数据每早删除
hubei-jinshennong
LAPTOP-S9HJSOEB\昊天 1 month ago
parent f8a6def6dc
commit 046a86a232

@ -1,5 +1,5 @@
#Generated by Maven
#Sat May 24 09:59:24 CST 2025
#Fri Jan 23 15:42:05 CST 2026
groupId=com.zhehekeji
artifactId=common
version=1.0.0

@ -0,0 +1,217 @@
package com.zhehekeji.web.service.client;
import com.sourceforge.snap7.moka7.S7Client;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
@Slf4j
@Service
public class DeleteServer {
@PostConstruct
public void PlcConnectionPool() {
CompletableFuture.runAsync(() -> cleanStorage("E:\\data\\mp4\\record\\live"));
}
/**
*
* @param rootPath "D:/storage"
*/
private void cleanStorage(String rootPath) {
try {
log.info("开始清理存储空间: {}", rootPath);
Path root = Paths.get(rootPath);
if (!Files.exists(root) || !Files.isDirectory(root)) {
log.error("存储路径不存在或不是目录: {}", rootPath);
return;
}
// 获取所有相机文件夹下的日期文件夹
List<DateFolder> allDateFolders = getAllDateFolders(root);
log.info("共找到 {} 个日期文件夹", allDateFolders.size());
// 按日期升序排序(最早的在前面)
allDateFolders.sort(Comparator.comparing(DateFolder::getDate));
// 第一轮清理:删除两个月前的文件夹
LocalDate twoMonthsAgo = LocalDate.now().minusMonths(2);
int deletedOld = deleteFoldersBeforeDate(allDateFolders, twoMonthsAgo);
log.info("删除两个月前的文件夹: {} 个", deletedOld);
// 检查磁盘空间
if (getDiskUsagePercent(root) < 70.0) {
log.info("磁盘空间充足({}%),清理完成", getDiskUsagePercent(root));
return;
}
// 第二轮清理:继续删除最旧的文件夹,直到空间充足或删完
int deletedMore = deleteOldestFolders(allDateFolders, twoMonthsAgo, root);
log.info("继续删除最旧的文件夹: {} 个", deletedMore);
log.info("存储空间清理完成,当前使用率: {}%", getDiskUsagePercent(root));
} catch (Exception e) {
log.error("清理存储空间失败", e);
}
}
/**
*
*/
private List<DateFolder> getAllDateFolders(Path root) throws IOException {
List<DateFolder> result = new ArrayList<>();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// 遍历根目录下的相机文件夹
Files.list(root)
.filter(Files::isDirectory)
.forEach(cameraDir -> {
try {
// 遍历相机文件夹下的日期文件夹
Files.list(cameraDir)
.filter(Files::isDirectory)
.forEach(dateDir -> {
try {
// 尝试解析文件夹名为日期
LocalDate date = LocalDate.parse(dateDir.getFileName().toString(), formatter);
result.add(new DateFolder(dateDir.toFile(), date, cameraDir.getFileName().toString()));
} catch (DateTimeParseException e) {
// 文件夹名不符合日期格式,跳过
}
});
} catch (IOException e) {
log.error("遍历相机文件夹失败: {}", cameraDir, e);
}
});
return result;
}
/**
*
*/
private int deleteFoldersBeforeDate(List<DateFolder> dateFolders, LocalDate beforeDate) {
int count = 0;
Iterator<DateFolder> iterator = dateFolders.iterator();
while (iterator.hasNext()) {
DateFolder folder = iterator.next();
if (folder.getDate().isBefore(beforeDate)) {
if (deleteFolder(folder.getFile())) {
count++;
}
iterator.remove();
}
}
return count;
}
/**
*
*/
private int deleteOldestFolders(List<DateFolder> dateFolders, LocalDate minDate, Path root) {
int count = 0;
Iterator<DateFolder> iterator = dateFolders.iterator();
while (iterator.hasNext() && getDiskUsagePercent(root) >= 70.0) {
DateFolder folder = iterator.next();
if (deleteFolder(folder.getFile())) {
count++;
log.info("删除文件夹: {}/{} (日期: {}), 当前使用率: {}%",
folder.getCameraName(), folder.getFile().getName(), folder.getDate(), getDiskUsagePercent(root));
}
iterator.remove();
}
return count;
}
/**
*
*/
private boolean deleteFolder(File folder) {
try {
if (folder.exists() && folder.isDirectory()) {
Files.walk(folder.toPath())
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
log.info("已删除文件夹: {}", folder.getAbsolutePath());
return true;
}
return false;
} catch (IOException e) {
log.error("删除文件夹失败: {}", folder.getAbsolutePath(), e);
return false;
}
}
/**
* 使
*/
private double getDiskUsagePercent(Path path) {
try {
FileStore store = Files.getFileStore(path);
long total = store.getTotalSpace();
long free = store.getUsableSpace();
long used = total - free;
return (used * 100.0) / total;
} catch (IOException e) {
log.error("获取磁盘空间失败", e);
return 100.0;
}
}
/**
*
*/
private static class DateFolder {
private final File file;
private final LocalDate date;
private final String cameraName;
public DateFolder(File file, LocalDate date, String cameraName) {
this.file = file;
this.date = date;
this.cameraName = cameraName;
}
public File getFile() {
return file;
}
public LocalDate getDate() {
return date;
}
public String getCameraName() {
return cameraName;
}
}
}

@ -13,11 +13,17 @@ import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.concurrent.*;
@Configuration
@ -57,6 +63,7 @@ public class PLCConnectionExample {
client.ConnectTo(plcIp,plcRack,plcSlot); // IP, Rack, Slot
connectionPool.offer(client);
}
}
@ -247,12 +254,11 @@ public class PLCConnectionExample {
// 读数据
@Scheduled(fixedDelay = POLL_INTERVAL)
void server(){
// 批量读取所有C1/C2/C3地址
Map<String, Integer> dataMap = readPlcDataTaskIds();
for (String key : addressMap.keySet()){
if (key.contains("out") || !key.contains("C")) {
continue;
}
int i = readPlcDataTaskId(addressMap.get(key));
for (String key : dataMap.keySet()){
int i = dataMap.get(key);
if (i == 0) continue;
if (taskMap.get(key) == null || taskMap.get(key) != i) {
log.info("任务号变化" + key + ":" + i);
@ -262,9 +268,7 @@ public class PLCConnectionExample {
executorService.submit(() -> processKey(i, plcId, key));
if(key.contains("C1")){
writePlcDataTaskId(key+"-out", i);
}
}
}
@ -335,6 +339,43 @@ public class PLCConnectionExample {
}
return false;
}
/**
* C1/C2/C3
* @return Map<key, value>{"001-C1": 100, "001-C2": 200, ...}
*/
public Map<String, Integer> readPlcDataTaskIds(){
S7Client client = getConnection();
try {
// 批量读取0-44字节区域
byte[] buffer = new byte[48];
int result = client.ReadArea(S7.S7AreaDB, dbNumber, 0, 48, buffer);
if (result != 0) {
updateConnection(client);
log.info("批量读取失败,错误码: " + result);
return new HashMap<>();
}
// 解析所有C1/C2/C3地址的值
Map<String, Integer> resultMap = new HashMap<>();
for (String key : addressMap.keySet()) {
if (key.contains("out") || !key.contains("C")) {
continue;
}
int offset = addressMap.get(key);
int value = S7.GetDIntAt(buffer, offset);
resultMap.put(key, value);
}
return resultMap;
} catch (Exception e) {
log.error("批量读取异常", e);
return new HashMap<>();
} finally {
returnConnection(client);
}
}
public boolean writePlcDataStatusErr(String plcId,int digit){
if (digit==1){

Loading…
Cancel
Save