【Windows共享文件】Java读取Windows环境共享文件夹

Java读取Windows环境共享文件夹(支持Win10/Win11等版本)

1、JCIFS介绍

JCIFS是使用纯Java开发的一个开源框架,通过smb协议访问远程文件夹。该框架同时支持Windows共享文件夹和Linux共享文件夹,不过,Linux共享文件夹需要安装Samba服务软件(官网:http://www.samba.org/)。

2、SMB协议

SMB协议(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的一种通信协议,它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务。
SMB协议是客户机/服务器型协议,客户机通过该协议可以访问服务器上的共享文件系统、打印机及其他资源。

控制面板 -> 程序和功能 -> 启用或关闭Windows功能 -> 勾选SMB

image-20230207163515751

3、设置共享文件夹

  1. 开启系统远程桌面功能:设置 -> 系统 -> 远程桌面 -> 启用远程桌面
  2. 创建或者选择一个文件夹
  3. 文件夹右键属性点击共享
  4. 选中的everyone选项,点击添加;设置级别权限,最后点击最下方的共享
  5. 文件夹右键属性,选择高级共享,点击权限,设置权限为完全控制,然后确定
  6. 打开网络和共享中心,点击更改高级共享设置,开启“启用文件和打印机共享”和“密码保护共享”,点击“保存更改”
  7. 在另一台电脑,win+R,输入mstsc打开远程桌面,输入共享文件夹电脑的ip地址及用户名密码进行连接测试。

image-20230206184239991

image-20230206184530163

3.1、设置某些文件或文件夹禁止访问

用户备注
Administrator系统权限最大的系统用户
Yohann我自己创建的用户

在这里我希望某些文件或者文件夹不让用户Yohann访问,则可以进行如下设置:

  • 文件夹:

image-20230207162530056

  • 文件:

image-20230207162756318

4、java读取共享文件夹中的文件

4.1、添加smb协议依赖

<!--smb协议获取共享文件夹内容-->
<dependency>
    <groupId>jcifs</groupId>
    <artifactId>jcifs</artifactId>
    <version>1.3.17</version>
</dependency>

4.2、创建连接,上传或获取文件内容

PS:由于工作业务没有涉及到下载远程文件,所以以下代码只有获取远程文件内容,如有需要可自行设计。

@Getter
@AllArgsConstructor
class Tuple2<T1, T2> {
    private final T1 first;
    private final T2 second;
    public static <T1, T2> Tuple2<T1, T2> of(T1 t1,T2 t2){
        return new Tuple2<>(t1,t2);
    }
}

    /**
     * 上传本地文件 -> 远程windows共享文件夹下
     *
     * @param localFilePath   本地文件全路径
     * @param ip              目标ip地址
     * @param account         账号
     * @param password        密码
     * @param shareFolderName 目标地址共享文件夹名称
     */
    public static void upLoadFile(String localFilePath, String ip, String account, String password,
                                  String shareFolderName) {
        InputStream in = null;
        OutputStream out = null;
        try {
            File localFile = new File(localFilePath);
            String remotePhotoUrl = "smb://" + account + ":" + password + "@" + ip + "/" + shareFolderName + "/"; //存放图片的共享目录
            SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS_");
            SmbFile remoteFile = new SmbFile(remotePhotoUrl + "/" + fmt.format(new Date()) + localFile.getName());
            // 尝试连接
            remoteFile.connect();
            log.info("connected to " + ip + " success!");

            in = new BufferedInputStream(new FileInputStream(localFile));
            out = new BufferedOutputStream(new SmbFileOutputStream(remoteFile));

            byte[] buffer = new byte[4096];
            // 读取长度
            int len = 0;
            while ((len = in.read(buffer, 0, buffer.length)) != -1) {
                out.write(buffer, 0, len);
            }
            // 刷新缓冲的输出流
            out.flush();
            log.info("文件:" + localFilePath.substring(localFilePath.lastIndexOf("\\") + 1) + " 上传至 " + remoteFile.getUncPath() + " 成功,目标文件名:" + remoteFile.getName());
        } catch (Exception e) {
            log.error("发生错误:" + e.getLocalizedMessage());
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (Exception e) {
                log.error("发生错误:流关闭失败");
            }
        }
    }

    /**
     * 获取远程共享文件夹下的文件及内容
     *
     * @param ip                 目标ip地址
     * @param account            账号
     * @param password           密码
     * @param shareFolderName    目标地址共享文件夹名称      例:ShareFolder
     * @param fileNameWithSuffix 共享文件夹下带后缀文件全路径   例:test/fyh/test.txt
     * @return 文件字节数组
     */
    public static byte[] getShareFile(String ip, String account, String password,
                                      String shareFolderName, String fileNameWithSuffix) {
        InputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            Tuple2<Boolean, SmbFile> tuple2 = testConnect(ip, account, password, shareFolderName, fileNameWithSuffix);
            if (tuple2.getFirst()) {
                SmbFile remoteFile = tuple2.getSecond();
                // 创建文件流
                in = new BufferedInputStream(new SmbFileInputStream(remoteFile));
                out = new ByteArrayOutputStream((int) remoteFile.length());
                // 读取文件内容
                byte[] buffer = new byte[4096];
                // 读取长度
                int len = 0;
                while ((len = in.read(buffer, 0, buffer.length)) != -1) {
                    out.write(buffer, 0, len);
                }
                // 刷新缓冲的输出流
                out.flush();
                return out.toByteArray();
            }
        } catch (Exception e) {
            log.error("下载远程文件出错:" + e.getLocalizedMessage());
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (Exception e) {
                log.error("发生错误:流关闭失败");
            }
        }
        return new byte[]{};
    }

    /**
     * 获取远程共享文件夹下的所有文件及内容
     *
     * @param ip              目标ip地址
     * @param account         账号
     * @param password        密码
     * @param shareFolderName 目标地址共享文件夹名称   例:ShareFolder
     * @return 共享文件夹下所有文件的名称及内容集合
     */
    public static List<String> getShareFiles(String ip, String account, String password,
                                             String shareFolderName) {
        InputStream in = null;
        ByteArrayOutputStream out = null;
        List<String> list = new ArrayList<>();
        try {
            Tuple2<Boolean, SmbFile> tuple2 = testConnect(ip, account, password, shareFolderName, null);
            if (tuple2.getFirst()) {
                SmbFile remoteFile = tuple2.getSecond();
                SmbFile[] smbFiles = remoteFile.listFiles();
                if (smbFiles.length <= 0) {
                    log.error("共享文件夹下为空");
                    throw new RuntimeException("共享文件夹下为空");
                }
                for (SmbFile smbFile : smbFiles) {
                    if (smbFile.isDirectory()) {
                        recursionAddFile(list, in, out, smbFile);
                        continue;
                    }
                    // 创建文件流
                    in = new BufferedInputStream(new SmbFileInputStream(smbFile));
                    out = new ByteArrayOutputStream((int) smbFile.length());
                    // 读取文件内容
                    byte[] buffer = new byte[4096];
                    // 读取长度
                    int len = 0;
                    while ((len = in.read(buffer, 0, buffer.length)) != -1) {
                        out.write(buffer, 0, len);
                    }
                    // 刷新缓冲的输出流
                    out.flush();
                    list.add(smbFile.getUncPath() + "\n" + out.toString());
                }
                return list;
            }
        } catch (Exception e) {
            log.error("下载远程文件出错:" + e.getLocalizedMessage());
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (Exception e) {
                log.error("发生错误:流关闭失败");
            }
        }
        return new ArrayList<>();
    }

    /**
     * 递归获取文件夹下的文件及内容
     *
     * @param list    文件列表
     * @param in      输入流
     * @param out     输出流
     * @param smbFile 文件夹
     */
    public static void recursionAddFile(List<String> list, InputStream in, ByteArrayOutputStream out, SmbFile smbFile) {
        try {
            if (smbFile.isDirectory()) {
                SmbFile[] smbFiles = smbFile.listFiles();
                if (smbFiles.length > 0) {
                    for (SmbFile file : smbFiles) {
                        if (file.isDirectory()) {
                            recursionAddFile(list, in, out, file);
                            continue;
                        }
                        // 创建文件流
                        in = new BufferedInputStream(new SmbFileInputStream(file));
                        out = new ByteArrayOutputStream((int) file.length());
                        // 读取文件内容
                        byte[] buffer = new byte[4096];
                        // 读取长度
                        int len = 0;
                        while ((len = in.read(buffer, 0, buffer.length)) != -1) {
                            out.write(buffer, 0, len);
                        }
                        // 刷新缓冲的输出流
                        out.flush();
                        list.add(file.getUncPath() + "\n" + out.toString());
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
        }
    }

    /**
     * 测试连接
     *
     * @param ip                 目标ip地址
     * @param account            账号
     * @param password           密码
     * @param shareFolderName    目标地址共享文件夹名称(如果不需要可以传null)      例:ShareFolder
     * @param fileNameWithSuffix 共享文件夹下带后缀文件全路径(如果不需要可以传null)   例:test/fyh/test.txt
     * @return 连接结果及返回值
     */
    public static Tuple2<Boolean, SmbFile> testConnect(String ip, String account, String password,
                                                       String shareFolderName, String fileNameWithSuffix) {
        if (StringUtils.isBlank(shareFolderName) && StringUtils.isNotBlank(fileNameWithSuffix)) {
            throw new RuntimeException("请指定共享文件夹");
        }
        // 创建远程文件对象
        String remotePhotoUrl = "smb://" + account + ":" + password + "@" + ip +
                (StringUtils.isBlank(shareFolderName) ? "" : "/" + shareFolderName + "/") +
                (StringUtils.isBlank(fileNameWithSuffix) ? "" : "/" + fileNameWithSuffix);
        SmbFile remoteFile = null;
        try {
            remoteFile = new SmbFile(remotePhotoUrl);
            // 尝试连接
            remoteFile.connect();
            log.info("connected to " + ip + " success!");
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            return Tuple2.of(false, null);
        }
        return Tuple2.of(true, remoteFile);
    }

4.3、测试

public static void main(String[] args) {
//        upLoadFile("D:\\test\\测试.txt", "10.18.110.126", "Administrator", "123456", "ShareFile");

//        System.out.println(new String(getShareFile("10.18.110.126", "Administrator", "123456", "ShareFile", "哈哈/三级目录/四级/四级.txt")));

        List<String> list = getShareFiles("10.18.110.126", "Yohann", "123456", "ShareFile");
        list.forEach(System.out::println);

//        Tuple2<Boolean, SmbFile> tuple2 = testConnect("10.18.110.126", "Administrator", "123456", null, null);
//        System.out.println(tuple2.getFirst());

//        Tuple2<Boolean, SmbFile> tuple2 = testConnect("10.18.110.126", "Administrator", "123456", "ShareFile", null);
//        if (tuple2.getFirst()) {
//            try {
//                SmbFile[] files = tuple2.getSecond().listFiles();
//                if (files.length <= 0) {
//                    log.error("null");
//                }
//                for (SmbFile file : files) {
//                    if (file.isDirectory()) {
//                        SmbFile[] smbFiles = file.listFiles();
//                        if (smbFiles.length <= 0) {
//                            log.error(file.getName() + " is null");
//                        }
//                        for (SmbFile smbFile : smbFiles) {
//                            System.out.println(smbFile.getName());
//                        }
//                    } else {
//                        continue;
//                    }
//                }
//            } catch (SmbException e) {
//                e.printStackTrace();
//            }
//        }
}

4.4、结果

image-20230207163201002

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Yohann*

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值