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

2023-11-16

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Windows共享文件】Java读取Windows环境共享文件夹 的相关文章

  • 在哈希图中存储字符和二进制数

    我正在尝试存储字母到二进制数的映射 这是我的映射 h 001 i 010 k 011 l 100 r 101 s 110 t 111 为此 我创建了一个哈希映射并存储了键值对 我现在想显示给定句子的相应二进制值 这是我的代码 package
  • JBoss AS 5 中的共享库应该放在哪里?

    我是 Jboss 新手 但我有多个 Web 应用程序 每个应用程序都使用 spring hibernate 和其他开源库和 portlet 所以基本上现在每个 war 文件都包含这些 jar 文件 如何将这些 jar 移动到一个公共位置 以
  • 在 Android 中绘制一条带有弯曲边缘的线

    I am using canvas drawLine to draw some line in android but the lines are too sharp but i need a curved edges 这里的 1 是我所拥
  • 如何以编程方式找出哪台计算机是 Windows 中的域控制器?

    我正在寻找一种方法来确定客户端计算机连接到的给定域的域控制器的名称 IP 地址 在我们公司 我们有很多用于测试的小型网络 其中大多数都有自己的小域 作为示例 其中一个域被命名为 TESTLAB 我有一个 Windows XP 工作站 它是
  • 将 HttpApi 与 I/O 完成端口结合使用

    我刚刚偶然发现了微软的HTTP 服务器 API http msdn microsoft com en us library aa364510 28v vs 85 29 aspx 简介中写道 HTTP 服务器 API 使应用程序能够通过 HT
  • 如何屏蔽 Protobuf 中的某些字段

    我找不到一种方法来屏蔽 protobuf 结构中的某些字段 我确实阅读了有关 FieldMaskUtil 的内容并尝试了几个示例 但它似乎做了相反的操作 即复制 FieldMask 中提到的字段 这与我想要的不同 这是示例结构和相应的测试代
  • 如何使用 BufferedReader 对象从 Java 中的一行读取多个整数值?

    我正在使用 BufferedReader 类读取 Java 程序中的输入 我想读取用户的输入 该用户可以在带空格的单行中输入多个整数数据 我想读取整数数组中的所有这些数据 输入格式 用户首先输入他 她想要输入的数字数量 然后在下一行中使用多
  • 用于防止滥用的 Servlet 过滤器? (DoS、垃圾邮件等)

    我正在寻找一个 Servlet 过滤器库 它可以帮助我保护我们的 Web 服务免受未经授权的使用和 DDoS 攻击 我们的网络服务有 授权客户 因此理想情况下 过滤器将帮助检测未经授权或行为不当的客户 或检测使用同一帐户的多个人 此外 我们
  • 尝试读取转储时“无法加载符号”

    我的一个应用程序有时会在 Win XP 计算机上导致 BSOD 为了了解更多信息 我加载了生成的 dmp 文件 来自 C Windows Minidump 但在执行此操作时在大部分读数中收到此消息 Symbols can not be lo
  • 如何使用 Spring MVC 和 Thymeleaf 添加静态文件

    我的问题是如何添加 CSS 和图像文件等静态文件 以便我可以使用它们 我正在使用 Spring MVC 和 Thymeleaf 我查看了有关此主题的各种帖子 但它们对我没有帮助 所以我才来问 根据这些帖子 我将 CSS 和图像文件放在res
  • 如何在命令提示符中检查 JAVA_OPTS 值?

    我们的应用程序部署 JBoss 服务器然后抛出错误 PermGen space 然后在 jboss bat 和配置文件中设置 permgen 变量中的 java OPTS JAVA OPTs 中是否有值 assige 如何检查 如何在命令提
  • Java 中 static 关键字如何工作?

    我正在阅读Java教程 http docs oracle com javase tutorial index html从一开始我就有一个问题static字段或变量上的关键字 作为Java said here http docs oracle
  • 如何创建共享网络目录或文件的超链接?

    我检查了以下两个相关讨论 1 如何创建指向本地可执行文件的超链接 https stackoverflow com questions 2815982 how do i make a hyperlink to a local executab
  • python:numpy 运行脚本两次

    当我将 numpy 导入到 python 脚本中时 该脚本会执行两次 有人可以告诉我如何阻止这种情况 因为我的脚本中的所有内容都需要两倍的时间 这是一个例子 usr bin python2 from numpy import print t
  • 在多模块项目中访问绑定适配器

    我有一个多模块项目 其中应用程序模块包含我的绑定适配器 而我的功能模块取决于我的应用程序模块 因为它是动态功能模块 应用程序 包含绑定适配器 gt 动态功能模块 存在布局的地方 我在所有模块中启用了数据绑定和 kapt 我无法成功构建应用程
  • 如何在 Java 中创建要打印到 JFrame 的 JLabels 数组

    我正在尝试制作一系列标签 每个标签都有一个来自函数的不同值 我不知道要使用的标签的确切数量 我的意思是可以打印任意数量的值 请帮我做这件事 很简单 只需一个方法返回一个数组或一些 JLabels 集合 并将它们全部添加到您的 JCompon
  • 无法在 BlackBerry Playbook 上设置音量

    我在更改黑莓游戏书的音量时遇到问题 首先 我将 Android 应用程序重新打包到 Palybook 应用程序 我需要使用搜索栏更改黑莓剧本的音量 并在搜索监听器中设置音频管理器音量 这是代码 audioManager AudioManag
  • JPA - 非主键字段上的 @OneToOne 关系不起作用

    我有一个 Spring Data JPA 后端 使用 Hibernate 作为 ORM 实现 这是模型 Person MailConfig id PK uid PK FK Person uid uid Entity
  • 将数组传递给函数名称冲突

    Specs GNU bash 版本 3 1 17 无法升级 Premise 我一直在摆弄数组 我想知道是否有任何方法可以让函数的本地变量与所述函数外部的数组同名 Example 在下面的示例中 我将尝试显示该问题 Working bin b
  • RecyclerView 不调用 onCreateViewHolder 或 onBindView

    没有收到任何错误 所有数据似乎都有效 由于某种原因 没有调用与视图相关的方法 我已确定以下事项 getItemCount 是唯一被调用的适配器方法 并且返回一个正整数值 我知道这将是你们将要查看的区域 构造函数正在被调用 成员变量有效 Pa

随机推荐

  • 驱动程序里ioctl下switch问题

    今天在写步进电机驱动程序时 switch语句引出3个分支 case 0 case 1 case 2 case 0 什么都不做 case 1让步进电机正向转动 case 2让步进电机反向转动 但是测试时 case 2怎么也动不起来 后来把ca
  • PLSQL Developer的配置方法

    1 下载32位的版本instantclient basic nt 11 2 0 3 0 zip 因为PLSQLDev是32位的 没有64位的版本 这 个和操作系统无关 2 instantclient下载完后是一个压缩文件 不需要安装 配置一
  • 服务器系统如何清理,服务器清理内存怎么清理

    服务器清理内存怎么清理 内容精选 换一换 本节操作指导您完成Windows操作系统云服务器磁盘空间清理 弹性云服务器匀出一部分磁盘空间来充当内存使用 当内存耗尽时 云服务器可以使用虚拟内存来缓解内存的紧张 但当内存使用率已经非常高时 频繁的
  • 关于HTTP协议,一篇就够了

    HTTP简介 HTTP协议是Hyper Text Transfer Protocol 超文本传输协议 的缩写 是用于从万维网 WWW World Wide Web 服务器传输超文本到本地浏览器的传送协议 HTTP是一个基于TCP IP通信协
  • TCP 连接管理机制(一)——TCP三次握手详解 + 为什么要有三次握手

    TCP是面向连接的协议 在通信之前需要先建立连接 其本质就是打开一个socket文件 这个文件有自己的缓冲区 如果要发送数据 上层把数据拷贝到发送缓冲区 如果是接收数据 OS直接把来自网络的数据拷贝到接收缓冲区里 那么三次握手期间 Serv
  • youversion.com的圣经无法使用、无法连接、无法下载离线版本的解决方法

    最近 youversion com的圣经无法使用 无法连接 无法下载离线版本了 这是一部很好用的圣经软件 以前一直用着 后来ipad越狱重新安装的时候就不能连接了 后来无意间发现原来是这个网站被和谐了 至于GCD为什么这么做 以咱的智商尚不
  • 接口自动化测试须知

    一 做接口测试需要哪些技能 做接口测试 需要的技能 基本就是以下几点 业务流 了解系统及内部各个组件之间的业务逻辑交互 数据流 了解接口的I O input output 输入输出 协议 包括http协议 TCP IP协议族 http协议
  • CMD查杀端口的两种方式

    第一种 netstat ano windows r输入cmd并打开 输入netstat ano 记住对应的6052 输入杀掉端口 taskkill pid 6052 f 第二种 netstat aon findstr 8080 直接输入ne
  • Win10 + VS2017 + Ceres配置

    前言 Ceres是google出品的一款基于C 的开源非线性优化库 官方文档 Ceres官方文档地址 依赖库 Eigen 官网 glog github gflags github Ceres github 配置过程 1 Eigen Eige
  • Python3 爬虫 requests+BeautifulSoup4(BS4) 爬取小说网站数据

    刚学Python爬虫不久 迫不及待的找了一个网站练手 新笔趣阁 一个小说网站 前提准备 安装Python以及必要的模块 requests bs4 不了解requests和bs4的同学可以去官网看个大概之后再回来看教程 爬虫思路 刚开始写爬虫
  • GPT专业应用:快速生成职位描述(JD)

    正文共 814 字 阅读大约需要 3 分钟 人力资源必备技巧 您将在3分钟后获得以下超能力 快速生成职位描述 Beezy评级 B级 经过简单的寻找 大部分人能立刻掌握 主要节省时间 推荐人 Kim 编辑者 Linda 图片由 Lexica
  • 数据中台与传统大数据平台有什么区别?_光点科技

    一 数据中台 数据中台是聚合和治理跨域数据 将数据抽象封装成服务 提供给前台以业务价值的逻辑概念 数据中台是在平台概念上的升级 不再单纯的将功能进行大杂烩 理念上 中台有几个特点 第一 更强调数据集中存储 统一管理 提供标准化的服务 第二
  • 【毕业设计】基于springboot + vue微信小程序商城

    目录 前言 创新点 亮点 毕设目录 一 视频展示 二 系统介绍 三 项目地址 四 运行环境 五 设计模块 前台 后台 六 系统功能模块结构图 数据库设计 七 准备阶段 使用真实支付 使用模拟支付 八 使用说明 九 登录后台 十 后台页面展示
  • 前端常用工具库方法整理

    欢迎点击领取 前端面试题进阶指南 前端登顶之巅 最全面的前端知识点梳理总结 前言 在闲余的时间整理一份我们可能用到的前端工具库方法 依赖库 名称 cropperjs 图片裁剪 exif js lrz 图片旋转问题 html2canvas d
  • React性能优化(完整版)

    我的博客 http wangxince site my demo markdown React 性能优化 1 减少 render 次数 shouldComponentUpdate PureComponent shouldComponentU
  • 计算机学习三宗罪——计算机达人成长之路(3)(转载自朱云翔老师笔记)

    以计算机学习不可浮躁 只有用心学习 深挖知识 才能基础扎实 才可以深入理解计算机专业知识 从而达到 他强由他强 清风拂山岗 他横由他横 明月照大江 的境界 万变不离其宗 编程程序具有三重境界 同样以VCD播放器为例 第一重境界就如同上面的同
  • 【译】用 `Wasmer` 进行插件开发 1

    译 用 Wasmer 进行插件开发 1 Using Wasmer for Plugins Part 1 译文 原文链接 https wiredforge com blog wasmer plugin pt 1 index html 原文 G
  • 05-BTC-网络

    目录 前言 比特币网络的工作原理 比特币网络 比特币网络中的每一个节点维护一个零度节点的集合 比特币系统中 每个节点要维护一个等待上链的交易的集合 比特币网络的传播属于best effort 前言 学习肖臻老师的 区块链技术与应用 公开课笔
  • vue-element-admin+flask实现数据查询项目

    本文分享一个使用vue element admin flask实现的一个数据查询项目 填写数据库连接信息和查询语句 即可展示查询到的数据 前提 已下载vue element admin并编译成功 前端 1 添加路由 src router i
  • 【Windows共享文件】Java读取Windows环境共享文件夹

    Java读取Windows环境共享文件夹 支持Win10 Win11等版本 1 JCIFS介绍 JCIFS是使用纯Java开发的一个开源框架 通过smb协议访问远程文件夹 该框架同时支持Windows共享文件夹和Linux共享文件夹 不过