三默网为您带来有关“SMB 协议操作共享盘”的文章内容,供您阅读参考。
SMB 协议操作共享盘
2023-01-21 19:35:10
1、添加依赖
<dependency>
<groupId>jcifs</groupId>
<artifactId>jcifs</artifactId>
<version>1.3.17</version>
</dependency>
2、示例工具类
import jcifs.smb.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.util.CollectionUtils;
import java.io.*;
import java.net.MalformedURLException;
import java.util.*;
/**
* 共享盘操作工具类
*/
@Slf4j
public class SmbFileUtils {
/**
* 递归获取共享盘某个目录下的文件列表
*
* @param container
* @param dir
* @return
* @throws SmbException
*/
public static void listSmbFilesByPrefixAndSuffix(List<SmbFile> container, SmbFile dir,
String filePrefix, String fileSuffix) throws SmbException {
SmbFile[] files = dir.listFiles();
Arrays.stream(files).forEach(smbFile -> {
try {
if (smbFile.isDirectory()) {
listSmbFilesByPrefixAndSuffix(container, smbFile, filePrefix, fileSuffix);
} else {
String fileName = smbFile.getName();
if (fileName.contains(filePrefix) && fileName.endsWith(fileSuffix.toLowerCase())) {
container.add(smbFile);
}
}
} catch (SmbException e) {
e.printStackTrace();
}
});
}
/**
* 根据规则递归获取共享盘某个目录下的文件
*
* @param sharedPath
* @return
* @throws SmbException
*/
public static List<String> listFileBySuffixAndLastSyncTime(String username, String password,
String sharedPath, String fileSuffix,
String lastSyncTime) throws Exception {
sharedPath = tailWrap(sharedPath);
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", username, password);
SmbFile dir = new SmbFile(sharedPath, auth);
dir.connect();
if (!dir.exists() || !dir.isDirectory()) {
throw new Exception(sharedPath + "路径不存在!");
}
List<SmbFile> files = new ArrayList<>();
//从指定目录开始获取目录下所有文件
recursiveDir(files, dir);
List<String> result = new ArrayList<>();
try {
if (!CollectionUtils.isEmpty(files)) {
String finalSharedPath = sharedPath;
files.forEach(file -> {
String name = file.getName();
boolean condition = false;
try {
condition = name.endsWith(fileSuffix.toLowerCase()) && CalendarUtil.lastModifiedBetween(file.lastModified(), lastSyncTime, CalendarUtil.getCurrentYMDHMS());
} catch (SmbException e) {
e.printStackTrace();
}
if (condition) {
//获取相对于指定路径的文件名
String fileNameWithRelativePath = file.getPath().substring(finalSharedPath.length() - 1);
result.add(fileNameWithRelativePath);
}
});
}
} catch (Exception e) {
e.printStackTrace();
return Collections.emptyList();
}
log.info("满足配置要求的文件数量为:->{}", result.size());
return result;
}
/**
* 根据规则遍递归遍历文件夹中的文件
*
* @param sharedPath
* @param prefix 文件前缀
* @param suffix
* @param lastSyncTime
* @return
* @throws Exception
*/
public static List<String> listFileByPrefixAndSuffixAndLastSyncTime(String username, String password,
String sharedPath, String prefix,
String suffix, String lastSyncTime) throws Exception {
sharedPath = tailWrap(sharedPath);
String currentTime = CalendarUtil.getCurrentYMDHMS();
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", username, password);
SmbFile dir = new SmbFile(sharedPath, auth);
dir.connect();
if (!dir.exists() || !dir.isDirectory()) {
throw new Exception(sharedPath + "路径不存在!");
}
List<SmbFile> files = new ArrayList<>();
recursiveDir(files, dir);
List<String> result = new ArrayList<>();
if (!CollectionUtils.isEmpty(files)) {
String finalSharedPath = sharedPath;
files.forEach(file -> {
String name = file.getName();
boolean condition = false;
try {
condition = name.contains(prefix) && name.endsWith(suffix.toLowerCase()) && CalendarUtil.lastModifiedBetween(file.lastModified(), lastSyncTime, currentTime);
} catch (SmbException e) {
e.printStackTrace();
}
if (condition) {
String fileNameWithRelativePath = file.getPath().substring(finalSharedPath.length() - 1);
result.add(fileNameWithRelativePath);
}
});
}
log.info("满足配置要求的文件数量为:->{}", result.size());
return result;
}
/**
* 根据规则遍递归遍历文件夹中的文件
*
* @param sharedPath
* @param prefix 文件前缀
* @param suffix
* @param fileTimeFormat
* @return
* @throws Exception
*/
public static List<String> listFileByPrefixAndSuffixAndTime(String username, String password,
String sharedPath, String prefix,
String suffix, String fileTimeFormat) throws Exception {
sharedPath = tailWrap(sharedPath);
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", username, password);
SmbFile dir = new SmbFile(sharedPath, auth);
dir.connect();
if (!dir.exists() || !dir.isDirectory()) {
throw new Exception(sharedPath + "路径不存在!");
}
List<SmbFile> files = new ArrayList<>();
recursiveDir(files, dir);
List<String> result = new ArrayList<>();
if (!CollectionUtils.isEmpty(files)) {
String finalSharedPath = sharedPath;
files.forEach(file -> {
String name = file.getName();
boolean condition = name.contains(prefix) && name.endsWith(suffix.toLowerCase()) && name.contains(fileTimeFormat);
if (condition) {
String fileNameWithRelativePath = file.getPath().substring(finalSharedPath.length());
result.add(fileNameWithRelativePath);
}
});
}
log.info("满足配置要求的文件数量为:->{}", result.size());
return result;
}
/**
* 递归获取目录下的文件列表
*
* @param list
* @param dir
* @return
*/
private static void recursiveDir(List<SmbFile> list, SmbFile dir) throws SmbException {
SmbFile[] smbFiles = dir.listFiles();
log.info("正在遍历的共享(SMB)文件夹为:->{}", dir.getPath());
Arrays.stream(smbFiles).forEach(smbFile -> {
try {
if (smbFile.isDirectory()) {
recursiveDir(list, smbFile);
} else if (smbFile.isFile()) {
list.add(smbFile);
}
} catch (SmbException e) {
e.printStackTrace();
}
}
);
}
/**
* 上传文件到共享盘
*
* @param aimDir
* @param fileName
* @param inputStream
* @return
*/
public static boolean upload(
String username, String password,
String aimDir, String fileName,
InputStream inputStream) {
try {
//检查文件名字是否携带目录层级
File file = new File(fileName);
String parent = file.getParent();
if (Objects.isNull(parent)) {
parent = "/";
}
if (parent.contains("\\")) {
parent = parent.replace("\\\\", "/");
}
if (!aimDir.endsWith("/") && !parent.startsWith("/")) {
aimDir = aimDir + "/";
}
String desDir = aimDir + parent;
if (!desDir.endsWith("/")) {
desDir += "/";
}
if (!createDir(username, password, desDir)) {
throw new RuntimeException("文件夹创建失败!->" + desDir);
}
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", username, password);
SmbFile aimFile = new SmbFile(desDir + file.getName(), auth);
aimFile.connect();
if (aimFile.isFile() && aimFile.exists()) {
aimFile.delete();
}
aimFile.createNewFile();
if (inputStream == null) {
throw new Exception(fileName + "的文件流为null!");
}
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
OutputStream outStream = new SmbFileOutputStream(aimFile);
outStream.write(buffer);
inputStream.close();
outStream.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public static boolean createDir(String username, String password, String path) {
try {
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", username, password);
SmbFile smbFileDir = new SmbFile(path, auth);
smbFileDir.connect();
boolean flag = smbFileDir.exists();
if (flag) {
return true;
}
smbFileDir.mkdirs();
log.info("目录:{},创建成功!", path);
return true;
} catch (MalformedURLException e) {
e.printStackTrace();
return false;
} catch (SmbException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* 获取文件流
*
* @param smbDir
* @return
* @throws IOException
*/
public static InputStream getFileInputStream(String username, String password, String smbDir, String fileName) {
SmbFileInputStream fis = null;
byte[] bytes = null;
try {
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", username, password);
if (!smbDir.endsWith("/") && !fileName.startsWith("/")) {
SmbFile smbFile = new SmbFile(smbDir + "/" + fileName, auth);
fis = new SmbFileInputStream(smbFile);
bytes = IOUtils.toByteArray(fis);
fis.close();
InputStream inputStream = new ByteArrayInputStream(bytes);
return inputStream;
} else {
SmbFile smbFile = new SmbFile(smbDir + fileName, auth);
fis = new SmbFileInputStream(smbFile);
bytes = IOUtils.toByteArray(fis);
fis.close();
InputStream inputStream = new ByteArrayInputStream(bytes);
return inputStream;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 删除文件
*
* @param smbDir
* @return
* @throws IOException
*/
public static boolean deleteFile(String username, String password, String smbDir, String fileName) throws IOException {
try {
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", username, password);
if (!smbDir.endsWith("/") && !fileName.startsWith("/")) {
SmbFile smbFile = new SmbFile(smbDir + "/" + fileName, auth);
if (smbFile.isFile() && smbFile.exists()) {
smbFile.delete();
}
} else {
SmbFile smbFile = new SmbFile(smbDir + fileName, auth);
if (smbFile.isFile() && smbFile.exists()) {
smbFile.delete();
}
}
return true;
} catch (MalformedURLException e) {
e.printStackTrace();
return false;
} catch (SmbException e) {
e.printStackTrace();
return false;
}
}
private static String tailWrap(String tail) {
if (!tail.endsWith("/")) {
tail += "/";
}
return tail;
}
}
注意事项:
①路径必须是smb://开头且以“/”结束 如 smb://127.0.0.1/D$/shareDisk/
②如果操作windows上的某个共享磁盘,若该磁盘没有指定共享名,须使用盘符加$代替,如操作D盘,路径里面不能写为D:\\ 应为"D$" 如 smb://127.0.0.1/D$/shareDisk/