共计 3981 个字符,预计需要花费 10 分钟才能阅读完成。
前言
最近有我的项目须要开发档案打包下载性能,其中蕴含很多大附件,我的项目应用 minio 存储且不在同一台服务器上,为了优化速度决定应用 windows 共享性能进行文件传输
SMB1.0
集成 jcifs 类库,次要实用于一些老旧零碎,但下载速度比较慢,仅作参考
此类库没有 maven 援用,官网地址:http://jcifs.samba.org/
注意事项:
设置 jcifs.smb.client.dfs.disabled 选项开启,能够进步传输速度
应用 NtlmPasswordAuthentication 认证代替 smb 协定 url 携带用户名明码形式,防止特殊字符传递造成认证失败
public static void downloadFile(String ip, String shareFolder, String filePath, String localDir) throws Exception {System.setProperty("jcifs.smb.client.dfs.disabled", "true");
String url = getFileUrl(ip, shareFolder, filePath);
SmbFile smbFile = new SmbFile(url);
smbFile.connect();
FileUtil.initfloderPath(localDir);
String localFilePath = localDir + "/" + smbFile.getName();
BufferedInputStream buf = new BufferedInputStream(new SmbFileInputStream(smbFile));
FileUtil.writeFile(localFilePath, FileUtil.convertStreamToByte(buf));
}
public static void downloadFileByAuth(String ip, String shareFolder, String userName, String password, String filePath, String localDir) throws Exception {System.setProperty("jcifs.smb.client.dfs.disabled", "true");
String url = getFileUrl(ip, shareFolder, filePath);
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(ip, userName, password);
SmbFile smbFile = new SmbFile(url, auth);
smbFile.connect();
FileUtil.initfloderPath(localDir);
String localFilePath = localDir + "/" + smbFile.getName();
BufferedInputStream buf = new BufferedInputStream(new SmbFileInputStream(smbFile));
FileUtil.writeFile(localFilePath, FileUtil.convertStreamToByte(buf));
}
public static String getFileUrl(String ip, String shareFolder, String filePath) {return "smb://" + ip + "/" + shareFolder + "/" + filePath;}
SMB2.0
集成 smbj 类库,实用于 windows server2012 及以上操作系统,默认装置开启无需额定配置
此类库 maven 援用很久没有公布最新版本,须要下载代码自行编译,github 地址:https://github.com/hierynomus…
经测试,500MB 文件传输大略比 minio 协定传输快了 4 秒左右,小文件传输速度根本保持一致
public static void downloadFileV2(String ip, String shareFolder, String filePath, String localDir) throws Exception {SMBClient client = new SMBClient(SmbConfig.createDefaultConfig());
Connection conn = client.connect(ip);
Session session = conn.authenticate(AuthenticationContext.anonymous());
downLoadSMB2(session, shareFolder, filePath, localDir);
}
public static void downloadFileByAuthV2(String ip, String shareFolder, String userName, String password, String filePath, String localDir) throws Exception {SMBClient client = new SMBClient(SmbConfig.createDefaultConfig());
Connection conn = client.connect(ip);
Session session = conn.authenticate(new AuthenticationContext(userName, password.toCharArray(), ip));
downLoadSMB2(session, shareFolder, filePath, localDir);
}
private static void downLoadSMB2(Session session, String shareFolder, String filePath, String localDir) throws Exception {
InputStream fis = null;
FileOutputStream os = null;
DiskShare diskShare = null;
try {diskShare = (DiskShare) session.connectShare(shareFolder);
if (!diskShare.fileExists(filePath)) {throw new FileNotFoundException(filePath);
}
if (!diskShare.isConnected())
diskShare = (DiskShare) session.connectShare(shareFolder);
com.hierynomus.smbj.share.File file = diskShare.openFile(filePath,
EnumSet.of(AccessMask.GENERIC_READ),
(Set) null,
SMB2ShareAccess.ALL,
SMB2CreateDisposition.FILE_OPEN,
(Set) null
);
fis = file.getInputStream();
FileUtil.initfloderPath(localDir);
String[] filePathList = filePath.split("\\/");
String localFilePath = localDir + "/" + filePathList[filePathList.length - 1];
os = new FileOutputStream(localFilePath);
byte[] b = new byte[4096];
int length;
while ((length = fis.read(b)) > 0) {os.write(b, 0, length);
}
} catch (IOException e) {throw e;} finally {IOUtils.close(os);
IOUtils.close(fis);
if (diskShare != null && diskShare.isConnected()) diskShare.close();}
}
445 端口被禁用解决办法
个别企业 / 政府我的项目为了系统安全会禁用 445 端口,而 445 端口禁用后文件共享性能无奈应用,此时咱们须要进行端口转发,行将客户端 445 端口转发到共享服务器端口 A,共享服务器将本地端口 A 转发到 445 即可实现共享,具体操作步骤如下,192.168.1.164 就是共享文件服务器的内网 ip
查看服务器转发规定
netsh interface portproxy show all
删除服务器转发规定
netsh interface portproxy reset
共享文件服务器
- 执行 CMD 代码
netsh interface portproxy add v4tov4 listenport=4455 listenaddress=192.168.1.164 connectport=445 connectaddress=127.0.0.1
netsh interface portproxy add v4tov4 listenport=4455 listenaddress=127.0.0.1 connectport=445 connectaddress=127.0.0.1
客户端服务器
- 敞开 Server 服务
- CMD 执行代码
netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=445 connectaddress=192.168.1.164 connectport=4455
- 重启零碎
正文完
发表至: springboot
2023-02-05