一、业务场景
公司内网环境,有部分比较古老的业务数据保存在一台windows服务器的共享目录里面。现在需要操作这个windows服务器的共享目录来上传下载删除文件。
二、共享目录
三、查了查资料,操作windows共享目录要通过smb协议。途中遇到一个问题,smb的协议版本问题导致无法连接windows共享目录,最后在GitHub上找到一个日本人对smb封装的依赖。
org.codelibs</groupId>
jcifs</artifactId>
2.1.19</version>
</dependency>
上代码:
上传文件返回链接
/** 共享目录上传
* upload
* @param file
* @return
*/
@SneakyThrows
public String upload(MultipartFile file,String custName,Long code) {
OutputStream out = null;
String filePath = "smb://" + host + path + code + "-" +custName+"/"+file.getOriginalFilename();
String path = "smb://" + host + this.path + code + "-" +custName;
try {
NtlmPasswordAuthenticator npa = new NtlmPasswordAuthenticator(null, userFile, password);
CIFSContext context = SingletonContext.getInstance().withCredentials(npa);
SmbFile sf = new SmbFile(path, context);
if (!sf.exists()){
sf.mkdirs();
}
SmbFile sf1 = new SmbFile(filePath, context);
InputStream inputStream = new BufferedInputStream(file.getInputStream());
out = new BufferedOutputStream(new SmbFileOutputStream(sf1));
byte[] buffer = file.getBytes();
//一次性读取所有文件
while (inputStream.read(buffer) != -1) {
out.write(buffer);
}
out.flush();
}catch (Exception e){
try {
out.close();
}catch (IOException e1){
throw new BusinessException("流关闭失败:"+e1.getMessage());
}
}
return this.path + code + "-" +custName+"/"+file.getOriginalFilename();
}
下载文件:
/**
* 共享目录
* @param response
*/
@SneakyThrows
public void xiazai(HttpServletResponse response,String addr,String contenType) {
String filePath = "smb://"+host+addr;
NtlmPasswordAuthenticator npa = new NtlmPasswordAuthenticator(null, userFile, password);
CIFSContext context = SingletonContext.getInstance().withCredentials(npa);
SmbFile sf = new SmbFile(filePath, context);
if (!sf.exists()){
throw new BusinessException("文件不存在");
}
InputStream in = null ;
ByteArrayOutputStream out = null ;
try {
sf.connect(); //尝试连接
//创建文件流
in = new BufferedInputStream(new SmbFileInputStream(sf));
out = new ByteArrayOutputStream((int)sf.length());
//读取文件内容
byte[] buffer = new byte[4096];
int len = 0;
while ((len = in.read(buffer, 0, buffer.length)) != - 1) {
out.write(buffer, 0, len);
}
if (StringUtils.isNotEmpty(contenType)){
response.setContentType(contenType);
}else {
response.setContentType("application/force-download");
}
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "no-store");
out.writeTo(response.getOutputStream());
out.flush();
}
catch (Exception e) {
String msg = "下载远程文件出错:" + e.getLocalizedMessage();
System.out.println(msg);
}
finally {
try {
if(out != null) {
out.close();
}
if(in != null) {
in.close();
}
}
catch (Exception e) {
throw new BusinessException(e.getMessage());
}
}
}
删除文件
/**
* 共享目录
* @param
*/
@SneakyThrows
public void remove(String addr) {
String filePath = "smb://"+host+addr;
NtlmPasswordAuthenticator npa = new NtlmPasswordAuthenticator(null, userFile, password);
CIFSContext context = SingletonContext.getInstance().withCredentials(npa);
SmbFile sf = new SmbFile(filePath, context);
if (!sf.exists()){
throw new BusinessException("共享目录或文件不存在:"+addr);
}
sf.delete();
}
创建目录
/**
* 共享目录
* @param path
*/
@SneakyThrows
public void mkdir(String path) {
String filePath = "smb://"+host+"/DocLib/"+this.path;
NtlmPasswordAuthenticator npa = new NtlmPasswordAuthenticator(null, userFile, password);
CIFSContext context = SingletonContext.getInstance().withCredentials(npa);
SmbFile sf = new SmbFile(filePath, context);
if (!sf.exists()){
sf.mkdir();
System.out.println("创建成功");
}
}
查询list
/**
* 共享目录
* @return
*/
@SneakyThrows
public Wrapper list() {
String filePath = "smb://"+host+"/DocLib/10";
NtlmPasswordAuthenticator npa = new NtlmPasswordAuthenticator(null, userFile, password);
CIFSContext context = SingletonContext.getInstance().withCredentials(npa);
SmbFile sf = new SmbFile(filePath, context);
List list = new ArrayList<>();
if (sf != null) {
for (int i = 0; i < sf.listFiles().length; i++) {
System.out.println(sf.listFiles()[i].getPath());
list.add(sf.listFiles()[i].getPath());
}
}
return WrapMapper.ok(list);
}