通过SMB协议上传,下载文件.



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 命令是删除所有保存的共享连接信息

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CIFS(Common Internet File System) 协议 CIFS 是一个新提出的协议,它使程序可以访问远程Internet计算机上的文件并要求此计算机的服务。CIFS 使用客户/服务器模式。客户程序请求远在服务器上的服务器程序为它提供服务。服务器获得请求并返回响应。CIFS是公共的或开放的SMB协议版本,并由Microsoft使用。SMB协议现在是局域网上用于服务器文件访问和打印的协议。象SMB协议一样,CIFS在高层运行,而不象TCP/IP协议那样运行在底层。CIFS可以看做是应用程序协议文件传输协议和超文本传输协议的一个实现。 SMB协议是基于TCP-NETBIOS下的,一般端口使用为139,445。 服务器信息块(SMB协议是一种IBM协议,用于在计算机间共享文件、打印机、串口等。SMB 协议可以用在因特网的TCP/IP协议之上,也可以用在其它网络协议如IPX和NetBEUI 之上。   SMB 一种客户机/服务器、请求/响应协议。通过 SMB 协议,客户端应用程序可以在各种网络环境下读、写服务器上的文件,以及对服务器程序提出服务请求。此外通过 SMB 协议,应用程序可以访问远程服务器端的文件、以及打印机、邮件槽(mailslot)、命名管道(named pipe)等资源。   在 TCP/IP 环境下,客户机通过 NetBIOS over TCP/IP(或 NetBEUI/TCP 或 SPX/IPX)连接服务器。一旦连接成功,客户机可发送 SMB 命令到服务器上,从而客户机能够访问共享目录、打开文件、读写文件,以及一切在文件系统上能做的所有事情。   从 Windows 95 开始,Microsoft Windows 操作系统(operating system)都包括了客户机和服务器 SMB 协议支持。Microsoft 为 Internet 提供了 SMB 的开源版本,即通用 Internet 文件系统 (CIFS)。与现有 Internet 应用程序如文件传输协议FTP)相比, CIFS 灵活性更大。对于 UNIX 系统,可使用一种称为 Samba 的共享软件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值