springboot 集成 smbFile 操作Windos共享文件夹

前言:最近某项目新增一个需求,需要将原本上传到tomcat 应用服务器上的文件上传到 windos 的共享文件夹,所以综合了网上资料,自己开始了如下尝试。

一、引入相关依赖

1、使用smbFile 操作共享文件夹需要用到以下jar 包

	<!-- https://mvnrepository.com/artifact/org.samba.jcifs/jcifs  java连接共享文件夹-->
    <dependency>
        <groupId>org.samba.jcifs</groupId>
        <artifactId>jcifs</artifactId>
        <version>1.3.14-kohsuke-1</version>
    </dependency>

二、使用smbFile连接到共享文件夹

1、测试连接到smbFile,一般常用的有两种连接方式

第一种就是直接连接到共享文件夹,如下

	//smb://xxx:xxx@192.168.43.108/testIndex/
	//xxx:xxx是共享机器的用户名密码
	String url="smb://wuxw:test@!1234@192.168.43.108/scmqc/";
	SmbFile file = new SmbFile(url);
	file.connect();
	if(file.exists()) {//如果文件存在,获取所有文件进行输出测试
		SmbFile[] files = file.listFiles();
		for (SmbFile f : files) {
			System.out.println(f.getName());
		}
	}

第二种就是密码中带@特殊符号的,在使用第一种登录方法时会验证失败,因为密码和文件ip区分使用的也是@
这时就可以使用第二种登录方法了,如下
这样就可以将地址与用户信息分离开来,先进行用户信息的认证,就不会验证失败了

//	此处采用优先验证登录用户信息的方法访问
	String ip="192.168.43.108";
	String url="smb://192.168.43.108/scmqc/";
	String name="wuxw\\test";
	String password="test@!1234";
	NtlmPasswordAuthentication auth =new NtlmPasswordAuthentication(ip, name, password);
	SmbFile file = new SmbFile(url,auth);
	file.connect();
	if(file.exists()){
		SmbFile[] files = file.listFiles();
		for(SmbFile f : files){
			System.out.println(f.getName());
		}
	}

三、Windows本地测试 使用 smbFile 上传、下载 共享文件夹中的文件

public  void testSmb(){
//		此处采用优先验证登录用户信息的方法访问
		String ip="192.168.43.108";
		String url="smb://192.168.43.108/scmqc/";
		String name="wuxw\\test";
		String password="test@!1234";
		NtlmPasswordAuthentication auth =new NtlmPasswordAuthentication(ip, name, password);
		SmbFile file = new SmbFile(url,auth);
		file.connect();
		if(file.exists()){
			SmbFile[] files = file.listFiles();
			for(SmbFile f : files){
				System.out.println(f.getName());
			}
		}
		// 下载文件的smb url地址、下载存放地址、用户认证信息
		smbFileDowload(url+"test.txt", "D:\\",auth);
		// 上传文件的smb url、文件地址、用户认证信息
		smbFileUpload(url, "D:\\test.txt", auth);
	}

1、上传

	//向共享目录上传文件
	public  void smbFileUpload(String remoteUrl,String localFilePath,NtlmPasswordAuthentication auth) {
		InputStream in = null;
		OutputStream out = null;
		try {
			File localFile = new File(localFilePath);
			String fileName = localFile.getName();
			SmbFile remoteFile = new SmbFile(remoteUrl+"/"+fileName,auth);
			in = new BufferedInputStream(new FileInputStream(localFile));
			out = new BufferedOutputStream(new SmbFileOutputStream(remoteFile));
			byte[] buffer = new byte[1024];
			while(in.read(buffer)!=-1){
				out.write(buffer);
				buffer = new byte[1024];
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				out.close();
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

2、下载

//    从共享目录下载文件
public void smbFileDowload(String remoteUrl,String localDir ,NtlmPasswordAuthentication auth) {
	InputStream in = null;
	OutputStream out = null;
	try {
		SmbFile remoteFile = new SmbFile(remoteUrl,auth);
		if(remoteFile==null){
			System.out.println("共享文件不存在");
			return;
		}
		String fileName = remoteFile.getName();
		File localFile = new File(localDir+File.separator+fileName);
		in = new BufferedInputStream(new SmbFileInputStream(remoteFile));
		out = new BufferedOutputStream(new FileOutputStream(localFile));
		byte[] buffer = new byte[1024];
		while(in.read(buffer)!=-1){
			out.write(buffer);
			buffer = new byte[1024];
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		try {
			out.close();
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

以上的测试在 Windows 本地的 java 环境下运行是完全没有问题的。

四、java 代码在 Linux 使用 smbFile 上传、下载 共享文件夹中的文件

首先我这边说明一下为什么会有这一步操作呢,可能因为技术还不到家,所以此点是本人结合项目实际操作加以记录,如果脑子灵活的或者有更好办法的,可以根据第三大点结合自己项目实际就完全不用看这一部分了。

因为在windows操作共享文件夹和 Linux 操作会稍微有点不一致,众所周知,我们写好的代码最终一般都是是要放到 Linux 环境中进行运行的,所以我这里说一下我这边目前将smbFile 放到项目中处理的一个思路。

上传:用户在web 页面上传的文件,先同时存放到tomcat 的应用服务器,然后再从应用服务器放到共享文件夹中,最后再把tomcat 应用服务器中的文件删除。
下载:先将共享文件夹中的文件下载到 tomcat 应用服务器,然后再从 tomcat 应用服务器下载到 用户浏览器,最后再把tomcat 应用服务器中的文件删除。

application.yml 中配置
smb:
    name: wuxw\test
    password: test@!1234
    ip: 192.168.43.108
    url: smb://192.168.43.108/scmqc/
    filePatch: \\192.168.43.108\scmqc\

#我将这些连接信息放在application.yml 文件中,此处通过注解进行获取
@Value("${smb.name}")
private String name;
@Value("${smb.password}")
private String password;
@Value("${smb.ip}")
private String ip;
@Value("${smb.url}")
private String url;

/**
 * 获取用户名密码,登录到共享文件夹
 * @return
 * @throws Exception
 */
public NtlmPasswordAuthentication connectionSmb() throws Exception {
//		此处使用优先验证登录用户信息的方法访问
        NtlmPasswordAuthentication auth =new NtlmPasswordAuthentication(ip, name, password);
        SmbFile file = new SmbFile(url,auth);
        file.connect();
        return auth;
    }

1、通过 smbFIle 上传文件

 /**
 * 向共享目录上传文件
 * @param localFilePath 要上传的文件
 * @param fileName 要上传的文件名
 */
   public void smbUpload(File localFilePath,String fileName) {
        InputStream in = null;
        OutputStream out = null;
        try {
            SmbFile remoteFile = new SmbFile(url+fileName,connectionSmb());
            in = new BufferedInputStream(new FileInputStream(localFilePath));
            out = new BufferedOutputStream(new SmbFileOutputStream(remoteFile));
            byte[] buffer = new byte[1024];
            while(in.read(buffer)!=-1){
                out.write(buffer);
                buffer = new byte[1024];
            }
            System.out.println("smb上传成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

2、 通过 smbFIle 下载文件

/**
     * 从共享目录下载文件
     * @param fileName  下载的文件名称
     * @param localDir  下载文件保存的路径
     * @return file
     */
    public File smbDownload(String fileName,String localDir ) {
        InputStream in = null;
        OutputStream out = null;
        File localFile = null;
        try {
//           拼接smb协议文件下载路径,初始化认证信息
            SmbFile remoteFile = new SmbFile(url+fileName,connectionSmb());
            if(remoteFile==null){
                System.out.println("共享文件不存在");
                return null;
            }
            localFile = new File(localDir+File.separator+fileName);
            in = new BufferedInputStream(new SmbFileInputStream(remoteFile));
            out = new BufferedOutputStream(new FileOutputStream(localFile));
            byte[] buffer = new byte[1024];
            while(in.read(buffer)!=-1){
                out.write(buffer);
                buffer = new byte[1024];
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return localFile;
    }

3、外部类中调用 smbFile 上传方法

//localFile 就是已经上传到 tomcat 应用服务器的文件,上传到Tomcat 应用服务器这部分我就不贴出来了
//fileName 就是文件名称
	smbFileUtil.smbUpload(localFile,fileName);

//得到要删除的文件进行删除
    File deleteFile = new File(localPath);
    //如果文件不存在
    if (!deleteFile.exists()) {
        throw new ZmmaxException("", "文件不存在");
    } else {//存在直接删除
        deleteFile.delete();
    }

4、外部类中调用 smbFile 下载方法

//libFile.getFileName()  就是需要下载的文件名称
//unixFileUpload = /opt/upload/  就是 tomcat 应用服务器下载地址
file = smbFileUtil.smbDownload(libFile.getFileName(),unixFileUpload);
 res.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(libFile.getFileTrueName(), "UTF-8"));
    //读取要下载的文件,保存到文件输入流
    FileInputStream in = new FileInputStream(file);
    OutputStream os = res.getOutputStream();
    byte[] bytes = new byte[1024];
    int len = 0;
    while ((len = in.read(bytes)) > 0) {
        os.write(bytes);
    }
    in.close();
    os.close();
    
    //得到要下载的文件,将tomcat服务器上文件删除
    File deleteFile = new File(unixFileUpload+libFile.getFileName());
    //如果文件不存在
    if (!deleteFile.exists()) {
        throw new ZmmaxException("", "文件不存在");
    } else {//存在直接删除
        deleteFile.delete();
    }

关注公众号查看更多资源
《springboot 集成 smbFile 操作Windos共享文件夹》
《springboot 集成 smbFile 操作Windos共享文件夹》

    原文作者:唱跑雨淋淋
    原文地址: https://blog.csdn.net/wxw1997a/article/details/101052665
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞