一、背景
在现代企业环境中,文件共享是一个常见的需求。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共享文件的资料请关注代码网其它相关文章!
发表评论