Java 复制远程共享文件夹到

参考文章:Java 复制远程共享文件夹到

1.共享文件

1.1 设置共享文件

1.2 选择文件夹,右键展开菜单面板,找到属性。

选择共享属性,点开可以添加 共享文件夹可以访问的用户。

远程访问需要启动 SMB/ 1.0/CIFS 文件共享支持。

1.3 开启SMB共享功能

进入 右键我的电脑 -> 属性 ->控制面板  -> 程序 -> 启用 或 关闭 windows 程序 找到  SMB/ 1.0/CIFS 文件共享支持,选中确认。

支持 服务端的 远程共享文件 服务就开启了。

2. 示例一

下面就工具类啦,其中 url 的格式为   smb://用户名:密码@IP地址/共享文件夹名称/

Maven

<!-- https://mvnrepository.com/artifact/org.samba.jcifs/jcifs -->
<dependency>
    <groupId>org.samba.jcifs</groupId>
    <artifactId>jcifs</artifactId>
    <version>1.3.3</version>
</dependency>

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>5.2.9.RELEASE</version>
</dependency>

Java代码 

package com.capgemini.cst.smb;

import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;
import org.springframework.util.FileCopyUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;

/**
 * @author fiend 2021-08-13 14:38:38
 */
public class SmbFileUtil {
    /**
     * @param url  远程地址的 url
     * @param path 本地存储文件的位置
     */
    public static void loadSmbFile(String url, String path) {
        try {
            SmbFile smbFile = new SmbFile(url);

            SmbFile[] files = smbFile.listFiles();
            for (SmbFile sf : files) {
                if (sf.isDirectory()) {
                    loadDirectory(sf, path);
                } else {
                    File file = new File(path + File.separator + sf.getName());
                    FileCopyUtils.copy(new SmbFileInputStream(sf), new FileOutputStream(file));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过递归加载文件夹
     */
    private static void loadDirectory(SmbFile smbFile, String path) throws IOException {
        StringBuilder sb = new StringBuilder(path + File.separator + smbFile.getName());
        File file = new File(sb.toString());
        if (!file.exists()) {
            file.mkdir();
        }

        // 获取文件夹下的所有子文件
        // CloseableIterator ci = smbFile.children();
        SmbFile[] sf = smbFile.listFiles();
        Iterator<SmbFile> it = Arrays.stream(sf).iterator();
        while (it.hasNext()) {
            SmbFile childrenFile = (SmbFile) it.next();
            if (childrenFile.isDirectory()) {
                loadDirectory(childrenFile, sb.toString());
            } else {
                File ifc = new File(sb.toString() + File.separator + childrenFile.getName());
                // 使用 SmbFileInputStream 读取远程文件
                FileCopyUtils.copy(new SmbFileInputStream(childrenFile), new FileOutputStream(ifc));
            }
        }
    }
}

3. 示例二

• 遍历目录

package com.capgemini.cst;

import jcifs.smb.SmbException;
import jcifs.smb.SmbFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.MalformedURLException;

/**
 * @author test 2021-08-13 14:44:43
 */
public class Test {
    public static final Logger logger = LoggerFactory.getLogger(Test.class);

    public static void test() throws MalformedURLException, SmbException {
        //URL注解: testcs 共享文件夹用户名,123456 共享文件夹密码,192.168.1.71 共享电脑IP
        String url = "smb://testcs:123456@192.168.1.71/save1/201612/测试二维码观看3/";
        logger.info("url---->" + url);

        SmbFile f = new SmbFile(url);
        if (f.exists()) {//判断是否有这个文件夹
            String[] filelist = f.list();
            for (int i = 0; i < filelist.length; i++) {//对这个案件目录下的文件进行遍历
                logger.info("------" + url + filelist[i] + "/");
                SmbFile file = new SmbFile(url + filelist[i] + "/");

                if (file.isDirectory()) {//对子目录进行遍历
                    String[] childFile = file.list();
                    for (String s : childFile) {//遍历子目录文件下的文件
                        logger.info("is------" + url + filelist[i] + "/" + s);
                        logger.info("childfile[j]---->" + s);
                    }
                }
            }
        }
    }
}

4. 示例三

摘要 

使用Java通过JCIFS框架读写共享文件夹,使用SMB协议,并支持域认证。

项目常常需要有访问共享文件夹的需求,例如读取共享文件夹存储的视频、照片和PPT等文件。那么如何使用Java读写Windows共享文件夹呢?

使用Java访问拥有全部读写权限的共享文件夹比较简单,和普通的目录没有什么区别。但是,如果从Linux服务器访问一个windows服务器上需要用户名和密码验证的共享文件夹,就需要一点点小技巧了。这里介绍一个开源的库JCIFS,他可以轻松满足此需求。

JCIFS是使用Java语言开发的一款开源框架,通过SMB协议访问远程共享文件夹,就像访问本地文件夹一样,简简单单。她同时支持Windows和Linux共享文件夹,不过,Linux共享文件夹需要安装Samba服务软件(官网:http://www.samba.org/)。

另外,通过挂载该共享文件夹到Linux服务器下也可以实现,此时不需要借助SMB协议。

Maven:

<!-- https://mvnrepository.com/artifact/org.samba.jcifs/jcifs -->
<dependency>
    <groupId>org.samba.jcifs</groupId>
    <artifactId>jcifs</artifactId>
    <version>1.3.3</version>
</dependency>

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>5.2.9.RELEASE</version>
</dependency>

代码示例:

SMB(Server Message Block)通信协议是微软(Microsoft)和英特尔(Intel)在1987年制定的协议,主要是作为Microsoft网络的通讯协议。SMB 是在会话层(session layer)和表示层(presentation layer)以及小部分应用层(application layer)的协议。通过设置“NetBIOS over TCP/IP”使得Samba不但能与局域网络主机分享资源,还能与全世界的电脑分享资源。

package com.capgemini.cst.smb;

import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;
import jcifs.smb.SmbFileOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;

/**
 * @author fiend 2021-08-13 16:16:57
 */
public class SmbFileUtil2 {
    private static Logger log = LoggerFactory.getLogger(SmbFileUtil.class);

    private static String USER_DOMAIN = "yourDomain";
    private static String USER_ACCOUNT = "yourAccount";
    private static String USER_PWS = "yourPassword";

    public static void main(String[] args) throws Exception {
        // remoteUrl 格式示例 【smb://132.20.2.33/CIMPublicTest/】
        // 目录
        String shareDir = "smb:// 132.20.2.33/CIMPublicTest/";
        listFiles(shareDir);
    }

    /**
     * @Title listFiles
     * @Description 遍历指定目录下的文件
     * @Date 2019-01-11 09:56
     */
    private static void listFiles(String shareDirectory) throws Exception {
        long startTime = System.currentTimeMillis();

        // 域服务器验证
        NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(USER_DOMAIN, USER_ACCOUNT,
                USER_PWS);
        SmbFile remoteFile = new SmbFile(shareDirectory, auth);
        log.info("远程共享目录访问耗时:【{}】", System.currentTimeMillis() - startTime);

        if (remoteFile.exists()) {
            SmbFile[] files = remoteFile.listFiles();
            remoteFile.listFiles(shareDirectory);

            for (SmbFile f : files) {
                log.info(f.getName());
            }
        } else {
            log.info("文件不存在");
        }
    }

    /**
     * @Title smbGet
     * @Param shareUrl 共享目录中的文件路径,如smb://132.20.2.33/CIMPublicTest/eg.txt
     * @Param localDirectory 本地目录,如tempStore/smb
     */
    public static void smbGet(String shareUrl, String localDirectory) throws Exception {
        NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(USER_DOMAIN, USER_ACCOUNT,
                USER_PWS);
        SmbFile remoteFile = new SmbFile(shareUrl, auth);
        if (!remoteFile.exists()) {
            log.info("共享文件不存在");
            return;
        }
        // 有文件的时候再初始化输入输出流
        InputStream in = null;
        OutputStream out = null;
        log.info("下载共享目录的文件 shareUrl 到 localDirectory");
        try {
            String fileName = remoteFile.getName();
            File localFile = new File(localDirectory + File.separator + fileName);
            File fileParent = localFile.getParentFile();
            if (null != fileParent && !fileParent.exists()) {
                fileParent.mkdirs();
            }
            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];
            }
            out.flush(); //刷新缓冲区输出流

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            out.close();
            in.close();
        }
    }

    /**
     * NtlmPasswordAuthentication类用于域认证,需要三个参数, 
     * 第一个是域名,如果没有,就赋值null, 第二个是用户名,第三个是密码。
     * 下面列举SMB协议的两个应用场景。
     * SmbFile类和Java的File类十分相似,使用其对象可以处理远程共享文件的读写。
     * @Title smbPut
     * @Description 向共享目录上传文件
     * @Param shareDirectory 共享目录
     * @Param localFilePath 本地目录中的文件路径
     * @date 2019-01-10 20:16
     */
    public static void smbPut(String shareDirectory, String localFilePath) {
        InputStream in = null;
        OutputStream out = null;
        try {
            File localFile = new File(localFilePath);

            String fileName = localFile.getName();
            SmbFile remoteFile = new SmbFile(shareDirectory + "/" + fileName);
            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];
            }
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

NtlmPasswordAuthentication类用于域认证,需要三个参数, 第一个是域名,如果没有,就赋值null, 第二个是用户名,第三个是密码。下面列举SMB协议的两个应用场景。SmbFile类和Java的File类十分相似,使用其对象可以处理远程共享文件的读写。

    /**
     * @Title smbPut
     * @Description 向共享目录上传文件
     * @Param shareDirectory 共享目录
     * @Param localFilePath 本地目录中的文件路径
     * @date 2019-01-10 20:16
     */
    public static void smbPut(String shareDirectory, String localFilePath) {
        InputStream in = null;
        OutputStream out = null;
        try {
            File localFile = new File(localFilePath);

            String fileName = localFile.getName();
            SmbFile remoteFile = new SmbFile(shareDirectory + "/" + fileName);
            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];
            }
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风情客家__

原创不易,觉得好的话给个打赏哈

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值