使用SpringBoot读取Windows共享文件的代码示例
作者:Jerryean99
在现代企业环境中,文件共享是一个常见的需求,Windows共享文件夹(SMB/CIFS协议)因其易用性和广泛的兼容性,成为了许多企业的首选,在Java应用中,尤其是使用Spring Boot框架时,如何读取Windows共享文件是一个值得探讨的话题,本文介绍了使用SpringBoot读取Windows共享文件
一、背景
在现代企业环境中,文件共享是一个常见的需求。Windows共享文件夹(SMB/CIFS协议)因其易用性和广泛的兼容性,成为了许多企业的首选。在Java应用中,尤其是使用Spring Boot框架时,如何读取Windows共享文件是一个值得探讨的话题。本文将介绍如何在Spring Boot应用中实现这一功能。
二、需求概述
项目需要对接各种的设备仪器,有很多的类型,例如串口传输、读取数据库、TCP/IP等等方式,这些解决办法是非常多的,但是有几台机器是做完实验就会在本地生成文件,一开始我们的想法也比较多,比如业务人员每天进行导入操作,后续考虑到尽量减小业务人员的操作,想到一个简单的方式就是定时读取每个机器电脑上的共享文件,根据它的修改时间读取所需的数据文件。
三、准备工作:windows共享文件夹配置
在windows系统中已经创建并共享了一个文件夹,记录下共享文件夹的网络路径,例如:\\服务器名\共享文件夹名。
确保你的Spring Boot应用所在的系统有权访问该共享文件夹。
配置的流程可以在网上检索一下,网上的示例也特别特别多,说明一下:可以单独建立一个共享的用户
例如用户名:share 密码 123456
四、代码示例
4.1 定时读取共享文件任务Task
@Component
@Slf4j
public class ReadShareFilesTask {
@Resource
InspectEquipmentInfoService inspectEquipmentInfoService;
/**
* 现在暂定每天执行
*/
@Scheduled(cron = "0 0 12 * * ?")
public void executeReadShareFiles() {
LocalDateTime dateTime = LocalDateTime.now().minusDays(1);
List<InspectEquipmentInfo> equipmentInfos = inspectEquipmentInfoService.lambdaQuery().eq(InspectEquipmentInfo::getEquipmentType, EquipmentTypeEnum.FILE_SHARING.getCode()).list();
equipmentInfos.forEach(equipmentInfo -> {
try {
log.info("开始读取设备:{}, 设备名称:{}, 设备ip:{}", equipmentInfo.getEquipmentCode(), equipmentInfo.getEquipmentName(), equipmentInfo.getEquipmentAddr());
FileReadStrategy fileReadStrategy = ClassExecuteServiceFactory.getFileReadStrategy(equipmentInfo.getEquipmentCode());
ValidationUtils.checkNotNull(fileReadStrategy, "策略未找到");
fileReadStrategy.listFile(equipmentInfo.getEquipmentAddr(),dateTime);
} catch (Exception e) {
log.error("读取设备:{}, 设备名称:{}, 设备ip:{} 失败", equipmentInfo.getEquipmentCode(), equipmentInfo.getEquipmentName(), equipmentInfo.getEquipmentAddr(), e);
}
});
}
}
4.2 工厂类
@Component
public class ClassExecuteServiceFactory implements ApplicationContextAware {
private final static Map<String, FileReadStrategy> CLASS_CODE_ABSTRACT_CLASS_HANDLE_MAP = new HashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, FileReadStrategy> types = applicationContext.getBeansOfType(FileReadStrategy.class);
types.values().forEach(e -> CLASS_CODE_ABSTRACT_CLASS_HANDLE_MAP.putIfAbsent(e.getCode(), e));
}
public static FileReadStrategy getFileReadStrategy(String code) {
return CLASS_CODE_ABSTRACT_CLASS_HANDLE_MAP.get(code);
}
}
4.3 文件读取接口策略
public interface FileReadStrategy {
String getCode();
void listFile(String ip, LocalDateTime dateTime);
void handleFileRead(InputStream inputStream, InspectEquipmentInfo info);
}
4.4 策略实现类
@Component
@Slf4j
public class SpectrometerFileReadStrategy implements FileReadStrategy {
@Resource
private InspectEquipmentInfoService equipmentInfoService;
@Resource
private InspectEquipmentRecordService recordService;
@Resource
private ReceiveEquipmentApi receiveEquipmentApi;
@Override
public String getCode() {
return ShareFilesAddressEnum.CODE.getCode();
}
@Override
public void listFile(String ip, LocalDateTime dateTime) {
InspectEquipmentInfo equipmentInfo = equipmentInfoService.lambdaQuery().eq(InspectEquipmentInfo::getEquipmentAddr, ip).one();
if (ObjectUtil.isEmpty(equipmentInfo)) {
log.error("该设备未配置到设备表当中,设备地址 {}", ip);
return;
}
SmbFileReader.listSmbFile(equipmentInfo, dateTime);
}
@Override
public void handleFileRead(InputStream inputStream, InspectEquipmentInfo info) {
try {
if (inputStream == null) {
log.error("无法找到ICP光谱仪CSV文件");
return;
}
//根据文件流解析数据
}
4.5 读取共享文件流通用类
@Slf4j
public class SmbFileReader {
public static void listSmbFile(InspectEquipmentInfo info, LocalDateTime dateTime) {
String path = info.getPath();
String ip = info.getEquipmentAddr();
String user = info.getUser();
String pass = info.getPass();
String suffix = info.getSuffix();
String code = info.getEquipmentCode();
SMBClient client = new SMBClient();
try (Connection connection = client.connect(ip)) {
AuthenticationContext ac = new AuthenticationContext(user, pass.toCharArray(), null);
Session session = connection.authenticate(ac);
try (DiskShare share = (DiskShare) session.connectShare(path)) {
for (FileIdBothDirectoryInformation f : share.list("", suffix)) {
FileTime changeTime = f.getLastWriteTime();
long windowsTimestamp = changeTime.toEpochMillis();
Instant instant = Instant.ofEpochMilli(windowsTimestamp);
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
if (dateTime.isAfter(localDateTime)) {
log.info("File : {},Change Time : {}, 跳过", f.getFileName(), localDateTime);
continue;
}
log.info("File : {},Change Time : {}", f.getFileName(), localDateTime);
String fileUrl = f.getFileName();
File smbFileRead = share.openFile(fileUrl, EnumSet.of(AccessMask.GENERIC_READ), null, SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN, null);
InputStream in = smbFileRead.getInputStream();
ClassExecuteServiceFactory.getFileReadStrategy(code).handleFileRead(in, info);
log.info("File : {} read success", fileUrl);
}
}
} catch (Exception e) {
log.error("Error reading file from SMB: {}", e.getMessage(), e);
}
}
}
五、总结
通过本文,我们了解了如何在Spring Boot应用中读取Windows共享文件。我们使用了jcifs库来处理SMB协议,并通过配置类、服务类和控制器类实现了文件的读取功能,希望这篇文章对你有所帮助。
以上就是使用SpringBoot读取Windows共享文件的代码示例的详细内容,更多关于SpringBoot读取Windows共享文件的资料请关注脚本之家其它相关文章!
