import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileOutputStream;
import org.apache.commons.io.IOUtils;
public class SMBUtils {
/**
* Description: 从共享目录拷贝文件到本地
*
* @param remoteUrl
* 共享目录上的文件路径
* @param localDir
* 本地目录
*/
public static byte[] smbGet(String remoteUrl,
NtlmPasswordAuthentication auth) {
byte[] bytes = {};
try {
SmbFile remoteFile = new SmbFile("smb://"+remoteUrl, auth);
if (remoteFile == null) {
//System.out.println("共享文件不存在");
return null;
}
bytes = IOUtils.toByteArray(remoteFile.getInputStream());
IOUtils.closeQuietly(remoteFile.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
return bytes;
}
/**
* 获取文件夹下的文件集合
* @param remoteUrl
* @param auth
* @return
* 2019-10-10
*/
public static SmbFile[] smbGetFiles(String remoteUrl,
NtlmPasswordAuthentication auth) {
SmbFile[] files = null;
try {
SmbFile remoteFile = new SmbFile("smb://"+remoteUrl, auth);
if (remoteFile == null||!remoteFile.isDirectory()) {
return null;
}
files = remoteFile.listFiles();
} catch (Exception e) {
e.printStackTrace();
}
return files;
}
/**
* 是否存在该文件
* @param remoteUrl
* @param auth
* @return
* 2019-9-29
*/
public static Boolean smbHas(String remoteUrl,
NtlmPasswordAuthentication auth) {
try {
SmbFile remoteFile = new SmbFile("smb://"+remoteUrl, auth);
if (remoteFile == null||!remoteFile.exists()) {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public static void autoMkdirs(String remotePath,NtlmPasswordAuthentication auth){
try {
SmbFile smbPath = new SmbFile("smb://"+remotePath,auth);
if (!smbPath.exists()){
smbPath.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/***
* 普通输入输出流传输文件,100M 10秒左右
* @param is
* @param path 以\结尾
* @param fileName
* @param auth
* 2019-11-1
*/
public static void streamPut(InputStream is,String path,String fileName) {
long beg = System.currentTimeMillis();
BufferedInputStream fis = null;
BufferedOutputStream smbfos = null;
try {
File smbFile = new File("\\\\"+path+fileName);
smbfos = new BufferedOutputStream(new FileOutputStream(smbFile));
fis = new BufferedInputStream(is);
IOUtils.copyLarge(fis, smbfos,new byte[1024*1024*8]);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("文件发送完毕,耗时:"
+ (System.currentTimeMillis() - beg) + "ms");
IOUtils.closeQuietly(fis);
IOUtils.closeQuietly(smbfos);
}
}
public static String smbPut(InputStream is,String path,String fileName,NtlmPasswordAuthentication auth) {
String result = null;
autoMkdirs(path,auth);
smbPut(is, path+fileName, auth);
return result;
}
/***
* SMB协议传输文件:测试100M 80多秒
* @param is
* @param remoteFile
* @param auth
* @return
* 2019-11-1
*/
public static void smbPut(InputStream is,String remoteFile,NtlmPasswordAuthentication auth) {
long beg = System.currentTimeMillis();
BufferedInputStream fis = null;
BufferedOutputStream smbfos = null;
// jcifs.Config.setProperty("jcifs.smb.client.dfs.disabled", "true");
// jcifs.Config.setProperty("resolveOrder","DNS");
try {
SmbFile smbFile = new SmbFile("smb://"+remoteFile,auth);
smbfos = new BufferedOutputStream(new SmbFileOutputStream(smbFile));
fis = new BufferedInputStream(is);
IOUtils.copyLarge(fis, smbfos,new byte[1024*1024*8]);
//IOUtils.copy(fis, smbfos);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("文件发送完毕,耗时:"
+ (System.currentTimeMillis() - beg) + "ms");
IOUtils.closeQuietly(fis);
IOUtils.closeQuietly(smbfos);
}
return result;
}
/**
* 写入文件 :大文件勿用此方法.内存溢出
* @param bytes
* @param remoteUrl
* @param auth
* 2019-9-29
*/
public static void smbPut(byte[] bytes,String remoteUrl, NtlmPasswordAuthentication auth) {
long beg = System.currentTimeMillis();
OutputStream os=null;
try {
SmbFile remoteFile = new SmbFile("smb://"+remoteUrl, auth);
os=remoteFile.getOutputStream();
IOUtils.write(bytes, os);
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(os);
}
System.out.println("写入完毕,耗时:"
+ (System.currentTimeMillis() - beg) + "ms");
}
/**
* Description: 从共享目录删除文件
*
* @param remoteUrl
* 共享目录上的文件路径
*/
public static void smbDel(String remoteUrl, NtlmPasswordAuthentication auth) {
try {
SmbFile remoteFile = new SmbFile("smb://"+remoteUrl, auth);
if (remoteFile.exists()) {
remoteFile.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public NtlmPasswordAuthentication getAuth(){
String fileServerAddress = "192.168.0.180";
String fileServerUserName = "administrator";
String fileServerPassword = "123";
NtlmPasswordAuthentication auth = new
NtlmPasswordAuthentication(fileServerAddress,fileServerUserName,fileServerPassword);
return auth;
}
public static void main(String[] args) {
SMBUtils.smbPut(is,allPath,newFileName+suffix,getAuth());
}
}
实际使用下来发现smb协议传输和普通输入输出流相差非常大,各种百度谷歌,还是没什么效果。
各种测试下来,用了一个变通方法,通过程序启动的时候保存文件共享服务器的登陆名和密码,然后再走Java IO,就不会报用户名密码错误了。
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* 执行windows的cmd命令工具类
*
*/
public class CMDUtil {
/**
* 执行一个cmd命令
* @param cmdCommand cmd命令
* @return 命令执行结果字符串,如出现异常返回null
*/
public static String excuteCMDCommand(String cmdCommand)
{
StringBuilder stringBuilder = new StringBuilder();
Process process = null;
try {
process = Runtime.getRuntime().exec(cmdCommand);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream(), "GBK"));
String line = null;
while((line=bufferedReader.readLine()) != null)
{
stringBuilder.append(line+"\n");
}
return stringBuilder.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 执行bat文件,
* @param file bat文件路径
* @param isCloseWindow 执行完毕后是否关闭cmd窗口
* @return bat文件输出log
*/
public static String excuteBatFile(String file, boolean isCloseWindow)
{
String cmdCommand = null;
if(isCloseWindow)
{
cmdCommand = "cmd.exe /c "+file;
}else
{
cmdCommand = "cmd.exe /k "+file;
}
StringBuilder stringBuilder = new StringBuilder();
Process process = null;
try {
process = Runtime.getRuntime().exec(cmdCommand);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream(), "GBK"));
String line = null;
while((line=bufferedReader.readLine()) != null)
{
stringBuilder.append(line+"\n");
}
return stringBuilder.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 执行bat文件,新开窗口
* @param file bat文件路径
* @param isCloseWindow 执行完毕后是否关闭cmd窗口
* @return bat文件输出log
*/
public static String excuteBatFileWithNewWindow(String file, boolean isCloseWindow)
{
String cmdCommand = null;
if(isCloseWindow)
{
cmdCommand = "cmd.exe /c start"+file;
}else
{
cmdCommand = "cmd.exe /k start"+file;
}
StringBuilder stringBuilder = new StringBuilder();
Process process = null;
try {
process = Runtime.getRuntime().exec(cmdCommand);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream(), "GBK"));
String line = null;
while((line=bufferedReader.readLine()) != null)
{
stringBuilder.append(line+"\n");
}
return stringBuilder.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
//启动调用如下代码,其中123是文件服务器密码,administrator是用户名
CMDUtil.excuteCMDCommand("net use \\\\192.168.0.189 123 /user:administrator")
//令外net use * /del /y 命令是删除所有保存的共享连接信息