文件传输服务应用1——java集成smb2/3实现文件共享方案详细教程和windows共享服务使用配置

news2024/12/24 15:55:26

在实际项目开发过程中,读取网络资源或者局域网内主机的文件是必要的操作和需求。而FTP(文件传输协议)和SMB(服务器消息块)是两种最为常见的文件传输协议。它们各自在文件传输领域拥有独特的优势和特点,但同时也存在一些差异。

本文以java集成smb为案例说明,其中SMB作为一种在Windows环境中广泛使用的文件共享协议,特别适合于局域网内的文件共享和协作,具体如何集成开发请详细阅读。

本文案以springboot2.1.5作为开发对象。

一.设置共享文件夹,也就是smb服务(以windows为测试对象)

1.首先在我的电脑下,找C盘之外的盘符新建一个文件夹,本例以SMB_Server做介绍

2.然后就可以用网络路径在局域网内的浏览器或者我的电脑访问共享的文件。

注意:

可以使用ip或者域来访问,其中域指的是smb服务电脑的设备名称(在我的电脑属性查看)

3.开启smb服务后,如果不能正常访问请查看以下网站处理

https://learn.microsoft.com/zh-CN/troubleshoot/windows-server/networking/dns-cname-alias-cannot-access-smb-file-server-share

二.java项目引入smb共享文件包

需要注意的是:

使用smb作为传输协议时,其存在协议版本的问题,需要同时引入smb1和smb2/3才能正常工作。

        <!--SMB共享文件-->
        <!-- https://mvnrepository.com/artifact/jcifs/jcifs -->
        <!--smb1-->
        <dependency>
            <groupId>jcifs</groupId>
            <artifactId>jcifs</artifactId>
            <version>1.3.17</version>
        </dependency>
        <!--smb2/3-->
        <dependency>
            <groupId>com.hierynomus</groupId>
            <artifactId>smbj</artifactId>
            <version>0.11.3</version>
        </dependency>

三.配置smb链接信息,构造java链接使用工具

1.新增smb-config.properties配置文件
##########################
# SMB配置信息
##########################

########### ———以下是Windows本地服务配置信息
smb.hostname=127.0.0.1
## 域名,没有可以为空
smb.domain=wp-pc
smb.username=wp
smb.password=123456
## 一定记得是共享目录名称,其他无须添加
smb.server.root=SMB_Server
## 需要访问的目录名称,后缀必须带"/"
smb.server.path=/project/opt/
## 本地存放SMB下载的结果文件的目录
smb.local.path=D:\\test\\project\\opt\\
# 本地存放运行对接需要的数据
smb.local.rundata=D:\\data\\rundata\\


############## ———以下是linux服务器配置信息
#smb.hostname=10.1.0.21
#smb.domain=
#smb.username=root
#smb.password=root
#smb.server.root=SMB_Server
#smb.server.path=/project/opt/
#smb.local.path=/root/demo/project/opt/
#smb.local.rundata=/root/demo/project/rundata/
@lombok.Data
@Component
/**
 * 加载SMB自定义配置文件
 * 配置文件需放在resources文件夹根目录
 */
@PropertySource("classpath:smb-config.properties")
public class SMBConfigInfo {

    @Value("${smb.hostname}")
    private String hostname;
    @Value("${smb.domain}")
    private String domain;
    @Value("${smb.username}")
    private String username;
    @Value("${smb.password}")
    private String password;
    @Value("${smb.server.root}")
    private String rootPath;
    @Value("${smb.server.path}")
    private String serverPath;
    @Value("${smb.local.rundata}")
    private String runDataPath;
}
 2.新增SMB共享文件工具,可支持登录,读取,下载,上传等操作
/**
 * SMB共享文件工具
 * 支持登录,读取,下载,上传等操作
 * @author wp
 */
@Component
public class SMBUtils {

    @Autowired
    private SMBConfigInfo smbConfigInfo;

    /**
     * 登录SMB服务
     *
     * @return
     */
    private NtlmPasswordAuthentication loginSMBServer() {
        UniAddress dc;
        NtlmPasswordAuthentication authentication = null;
        try {
            dc = UniAddress.getByName(smbConfigInfo.getHostname());
            authentication = new NtlmPasswordAuthentication(smbConfigInfo.getDomain(), smbConfigInfo.getUsername(), smbConfigInfo.getPassword());
            SmbSession.logon(dc, authentication);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("loginSMBServer fail:" + smbConfigInfo.toString());
            return null;
        }
        return authentication;
    }


    /**
     * 从SMB服务器下载文件到本地路径
     * 路径格式:smb://192.168.1.21/test/新建文本文档.txt
     * smb://username:password@192.168.1.21/test
     *
     * @param remoteUrl 远程路径
     * @param localDir  要写入的本地路径
     */
    public void getSMBFileByDown(String remoteUrl, String localDir) {
        InputStream in = null;
        OutputStream out = null;
        NtlmPasswordAuthentication auth = loginSMBServer();
        if (auth == null) {
            return;
        }
        try {
            SmbFile remoteFile = new SmbFile(remoteUrl, auth);
            if (!remoteFile.isFile()) {
                System.out.println("共享文件不存在");
                return;
            }
            String fileName = remoteFile.getName();
            File fileDir = new File(localDir);
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }
            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();
            }
        }
    }

    /**
     * 通过读取SMB远程文件获得输入流
     * 如果输入流在别处使用的时候,一定记得不要先关闭
     * 另外流不能直接上传或者操作,否则有异常
     * 须先下载到本地,然后再处理
     *
     * @param remoteUrl
     * @return
     */
    public InputStream getInputStreamBySMBFile(String remoteUrl) {
        NtlmPasswordAuthentication auth = loginSMBServer();
        if (auth == null) {
            return null;
        }
        InputStream in = null;
        try {
            SmbFile remoteFile = new SmbFile(remoteUrl, auth);
            if (!remoteFile.isFile()) {
                System.out.println("共享文件不存在");
                return in;
            }
            in = new BufferedInputStream(new SmbFileInputStream(remoteFile));
            byte[] buffer = new byte[1024];
            while (in.read(buffer) != -1) {
                buffer = new byte[1024];
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            /*try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }*/
        }
        return in;
    }


    /**
     * 从本地上传文件到指定SMB指定目录
     *
     * @param remoteUrl     文件的全路径+文件名称
     * @param localFilePath
     */
    public void getSMBFileByUpload(String remoteUrl, String localFilePath) {
        NtlmPasswordAuthentication auth = loginSMBServer();
        if (auth == null) {
            return;
        }
        InputStream in = null;
        OutputStream out = null;
        try {
            File localFile = new File(localFilePath);
            String fileName = localFile.getName();
            SmbFile remoteFile = new SmbFile(remoteUrl + "/" + fileName, auth);
            if (!remoteFile.exists()) {
                remoteFile.createNewFile();
            }
            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();
            }
        }
    }

    /**
     * 读取SMB服务指定目录的文件
     * smb://administrator:dibindb@10.1.1.12/share/aa.txt
     *
     * @param remoteUrl
     * @param fileName
     * @return
     */
    public String readSMBFile(String remoteUrl, String fileName) {
        NtlmPasswordAuthentication auth = loginSMBServer();
        if (auth == null) {
            return "";
        }
        SmbFileInputStream smbIn = null;
        StringBuffer strBu = new StringBuffer();
        try {
            SmbFile smbCatalog = new SmbFile(remoteUrl, auth);
            if (!smbCatalog.exists()) {
                smbCatalog.mkdirs();
            }
            SmbFile smbFile = new SmbFile(remoteUrl + fileName, auth);
            if (!smbFile.isFile()) {
                smbFile.createNewFile();
            }
            // 得到文件的大小
            int length = smbFile.getContentLength();
            byte buffer[] = new byte[ConstantDataList.SYSTEM_BUFFER_SIZE];
            // 建立smb文件输入流
            smbIn = new SmbFileInputStream(smbFile);
            int leng = -1;
            while ((leng = smbIn.read(buffer)) != -1) {
                strBu.append(new String(buffer, 0, leng));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                smbIn.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return strBu.toString();
    }

    /**
     * 将jsonStr写入SMB指定的目录文件中
     *
     * @param remoteUrl
     * @param fileName
     * @param jsonStr
     */
    public void writeSMBFile(String remoteUrl, String fileName,
                             String jsonStr) {

        NtlmPasswordAuthentication auth = loginSMBServer();
        if (auth == null) {
            return;
        }
        //将str转化成输入流
        ByteArrayInputStream smbIn = new ByteArrayInputStream(jsonStr.getBytes());
        SmbFileOutputStream out = null;
        try {
            SmbFile smbCatalog = new SmbFile(remoteUrl, auth);
            if (!smbCatalog.exists()) {
                smbCatalog.mkdirs();
            }
            SmbFile smbFile = new SmbFile(remoteUrl + fileName, auth);
            if (!smbFile.isFile()) {
                smbFile.createNewFile();
            }
            out = new SmbFileOutputStream(smbFile);
            // 得到文件的大小
            byte buffer[] = new byte[4096];
            int leng = -1;
            while ((leng = smbIn.read(buffer)) != -1) {
                out.write(buffer, 0, leng);
            }
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                smbIn.close();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    
}

 四.测试java链接操作smb功能

通过后台日志打印,可以清楚的看到链接,登录以及获取权限等操作信息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1690152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3DMax

先转换为可编辑多边形 按“1”选择为点&#xff0c;点击目标焊接&#xff08;CtrlShiftw&#xff09;&#xff0c;然后点击一个顶点拉到另一个定点上&#xff1b; 选择一个面&#xff0c;点击塌陷&#xff08;CtrlAltC&#xff09;&#xff0c;四点合并为一个点&#xff1b; …

Ai指令-公众号内训课:学会ai指令+公众号的底层逻辑(7节课)

课程目录 第一课:详解公众号的流量机制.mp4 第二课:快速搞定公众号号设化装修.mp4 第三课:一期学员直呼牛X的课程&#xff0c;正确的爆文利用姿势.mp4 第五课:颗粒度级别拆解AI公众号爆文.mp4 第六课:AI提示词进阶技巧课。提示词自动化.mp4 第七课.实操演示提示词撰写工作…

element-ui输入框和多行文字输入框字体不一样解决

element-ui的type"textarea"的字体样式与其他样式不同 <el-input type"textarea"></el-input> <el-input ></el-input>设置&#xff1a; .el-textarea__inner::placeholder {font-family: "Helvetica Neue", Helvetic…

GPIO模拟spi时序点亮数码管

目录 spi.h spi.c main.c 实验效果 spi.h #ifndef __SPI_H__ #define __SPI_H__#include "stm32mp1xx_gpio.h" #include "stm32mp1xx_rcc.h"//spi初始化 void spi_init(); //spi写入数据 void spi_write(unsigned char data);#endif spi.c #include…

C#编程-.NET Framework使用工具类简化对象之间的属性复制和操作

在C#编程中&#xff0c;对象之间的属性复制和操作是一个常见的需求。为此&#xff0c;.NET Framework提供了多种实用工具库&#xff0c;如AutoMapper、ValueInjecter和ExpressMapper。这些库通过简化代码&#xff0c;提高了开发效率。本文将介绍这些工具库&#xff0c;比较它们…

Html基础笔记

Html超文本标记语言 (HyperText Markup Language) 超文本 指的是网页中可以显示的内容(图片,超链接,视频,) 标记语言 标记–>标签(标注) 例如:买东西的时候—>商品具有标签,看到标签就知道商品的属性(价格,材质,型号等,) 标记语言就是提供了很多的标签,不同的标签…

Android 几个简单的自定义对话框介绍

Android 几个简单的自定义对话框介绍 文章目录 一、前言二、对话框相关内容1、效果2、对话框显示的调用代码&#xff08;1&#xff09;原生对话框代码&#xff1a;&#xff08;2&#xff09;自定义对话框代码&#xff1a; 3、对话框SweetAlertDialog 主要实现代码&#xff1a;4…

在DAYU200上实现OpenHarmony跳转拨号界面

一、简介 日常生活中&#xff0c;打电话是最常见的交流方式之一&#xff0c;那么如何在OpenAtom OpenHarmony&#xff08;简称“OpenHarmony”&#xff09;中进行电话服务相关的开发呢&#xff1f;今天我们可以一起来了解一下如何通过电话服务系统支持的API实现拨打电话的功能…

噱头还是风口?剖析AI短剧出海的未来

导语 |去年以来&#xff0c;低成本、高回报的土味短剧在国内爆火&#xff0c;而这股风也成功地刮到海外。2024 年&#xff0c;越来越多的人把目光投向了拥有庞大市场的国外“蓝海”&#xff0c;当人们还在高谈阔论 Sora 是否颠覆影视行业的时候&#xff0c;AI 已经在出海短剧中…

Linux系统搭建Tale个人博客网站并实现无公网IP访问本地博客

文章目录 前言1. Tale网站搭建1.1 检查本地环境1.2 部署Tale个人博客系统1.3 启动Tale服务1.4 访问博客地址 2. Linux安装Cpolar内网穿透3. 创建Tale博客公网地址4. 使用公网地址访问Tale 前言 今天给大家带来一款基于 Java 语言的轻量级博客开源项目——Tale&#xff0c;Tale…

【嵌入式芯片开发】不使用MicroLib的串口重定向万能预编译配置(适用于ARMCC、AC6等不同的编译器及版本)

【嵌入式芯片开发】不使用MicroLib的串口重定向万能预编译配置&#xff08;适用于ARMCC、AC6等不同的编译器及版本&#xff09; 文章目录 基本的串口重定向接收中断与scanf不能同时工作重定向卡死、低功耗一直唤醒 串口重定向万能预编译配置附录&#xff1a;Cortex-M架构的Sys…

【设计模式深度剖析】【5】【创建型】【原型模式】| 类比群发邮件,加深理解

&#x1f448;️上一篇:建造者模式 | 下一篇:创建型设计模式对比&#x1f449;️ 目录 原型模式(Prototype Pattern)概览定义英文原话直译 3个角色类图1. 抽象原型&#xff08;Prototype&#xff09;角色2. 具体原型&#xff08;Concrete Prototype&#xff09;角色3. 客户…

【cocos creator 】生成六边形地图

想要生成一个六边形组成的地图 完整代码示例 以下是完整的代码示例&#xff0c;包含了注释来解释每一步&#xff1a; cc.Class({extends: cc.Component,properties: {hexPrefab: {default: null,type: cc.Prefab},mapWidth: 10, // 网格的宽度&#xff08;六边形的数量&am…

基于Pytorch框架全连接神经网络对手势图片识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 手势识别是计算机视觉领域的一个重要研究方向&#xff0c;具有广泛的应用前景&#xff0c;如人…

react中怎么为props设置默认值

在React中&#xff0c;你可以使用ES6的类属性&#xff08;class properties&#xff09;或者函数组件中的默认参数&#xff08;default parameters&#xff09;来定义props的默认值。 1.类组件中定义默认props 对于类组件&#xff0c;你可以在组件内部使用defaultProps属性来…

基于Java的推箱子游戏设计与实现(论文 + 源码)

【免费】关于基于JAVA的推箱子游戏.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89325018 基于Java的推箱子游戏设计与实现 摘 要 社会在进步&#xff0c;人们生活质量也在日益提高。高强度的压力也接踵而来。社会中急需出现新的有效方式来缓解人们的压力。…

Java开发大厂面试第20讲:什么是分布式锁?Redi 怎样实现的分布式锁?

“锁”是我们实际工作和面试中无法避开的话题之一&#xff0c;正确使用锁可以保证高并发环境下程序的正确执行&#xff0c;也就是说只有使用锁才能保证多人同时访问时程序不会出现问题。 我们本课时的面试题是&#xff0c;什么是分布式锁&#xff1f;如何实现分布式锁&#xf…

秋招突击——算法打卡——5/24——无重复字符的最长字串

题目描述 实现代码 // 无重复字符的最长子串 int lengthOfLongestSubstring(string s) {int l 0,r 0;int res 0;unordered_map<char,int> temp;while(l < s.size()){temp[s.at(l)] l;for (r l 1; r < s.size() ; r) {if(temp.count(s.at(r))) break;else te…

Python UDP编程简单实例

TCP是建立可靠的连接&#xff0c;并且通信双方都可以以流的形式发送数据。 相对于TCP&#xff0c;UDP则是面向无连接的协议&#xff0c;不需要建立连接&#xff0c;只需要知道对方IP地址和端口号&#xff0c;就可以直接发送数据包。但是只管发送不保证到达。 虽然UDP传输数据…

详解 UML 中的关系概念

关联&#xff08;Association&#xff09; 表示两个类之间的一种语义性联系。例如: 学生与班级之间的关联关系。 有向关联&#xff08;Directed Association&#xff09; 关联关系有方向性,表示一个类能访问另一个类,但不一定反过来。例如: 教师能查看学生的成绩,但学生不能查…