用JCIFS下载windows共享文件


有同事在外地,他们提供给我的软件包也是在他们本地的,因此开启了windows自带的共享,这样就方便我们取包。由于地域限制,我们访问非常的慢,因此考虑到用Jenkins来触发,下载软件包到我们本地服务器。


先分析下这个需要怎么处理。因为windows共享属于SMB协议,不同的windows系统SMB协议版本不同,目前常见的win7最高支持SMB2,因此对于SMB协议,可以用「JCIFS」库来操作。

  • 技术栈:Java
  • 知识:JCIFS、SMB

引用JCIFS

创建一个maven工程,然后在pom.xml中添加依赖包。最新的是1.3.18。

<dependency>
            <groupId>jcifs</groupId>
            <artifactId>jcifs</artifactId>
            <version>1.3.18</version>
</dependency>

访问共享

访问共享有几种方式,用匿名访问,用户名访问,带域名访问共享,这几种用的不同的方法。我把我自己遇到的坑提出来,希望能帮助到其他人。

  1. 匿名访问,需要的访问路径加上一个常量ANONYMOUS
import jcifs.smb.SmbFile;
String remoteUrl= "smb//1.1.1.1/smb/package.zip";
smbFile = new SmbFile(remoteUrl, NtlmPasswordAuthentication.ANONYMOUS);
  1. 用户名访问,直接在路径里面体现用户名和密码,以及域名
import jcifs.smb.SmbFile;
String remoteUrl= "smb//domain;user:passwd@1.1.1.1/smb/package.zip";
SmbFile smbFile = new SmbFile(remoteUrl);

2.1 JCIFS访问共享的时候密码用户名包含了百分号或者特殊符号 这里有一个坑,就是用户名和密码包含了%以及其他的特殊字符,会导致验证失败。所以下面这个问题就可以解决。 3. 先用NtlmPasswordAuthentication,后Get

import jcifs.smb.SmbFile;
import jcifs.smb.NtlmPasswordAuthentication;

String remoteUrl= "smb//1.1.1.1/smb/package.zip";
NtlmPasswordAuthentication ntPassAuth = new
        NtlmPasswordAuthentication(domain, user, passwd);
SmbFile smbFile = new SmbFile(remoteUrl, ntPassAuth);

还有一些其他的用法,这里没有用到,可以参考官方API。

获取文件

获取文件用这个SmbFileInputStream,一句话就搞定;

import jcifs.smb.SmbFileInputStream;
in = new BufferedInputStream(new SmbFileInputStream(smbFile));

写入文件

写到本地一样和输入一样的,一句话就可以搞定。

import jcifs.smb.SmbFileInputStream;
out = new BufferedOutputStream(new FileOutputStream(localFile));

Demo

import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;
import jcifs.smb.SmbFileOutputStream;
import jcifs.smb.NtlmPasswordAuthentication;

InputStream in = null;
OutputStream out = null;
long a = new Date().getTime();
try {
	// authentication
    NtlmPasswordAuthentication ntPassAuth = new
            NtlmPasswordAuthentication("ad.xxx.com", "testuser", "pass%word");
    // access cifs share
    SmbFile smbFile = new SmbFile(remoteUrl, ntPassAuth);
    String fileName = smbFile.getName();
    int length = smbFile.getContentLength();
    // create file as same name
    File localFile = new File(localDir + File.separator + fileName);
    in = new BufferedInputStream(new SmbFileInputStream(smbFile));
    out = new BufferedOutputStream(new FileOutputStream(localFile));
    byte[] buffer = new byte[1024 * 1024]; // a buff 1M
    int sum = 0;
    while ((in.read(buffer)) != -1) {
        out.write(buffer);
        sum += buffer.length;
        System.out.println("Complete: "+sum *100.0/length+"%");
        buffer = new byte[1024];
    }
} catch (Exception e) {
    e.printStackTrace();
} finally {
    try {
        out.close();
        in.close();
        long b = new Date().getTime();
        int c = (int)((b- a) / 1000);
        System.out.println("used time: "+ c +"s");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

扩展阅读


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java开发必知必会

web项目中如何选择日志组件(SLF4J、Log4J2、logback)

    为什么使用SLF4J与其他组件结合使用比单独使用log4j2或者java.util.logging要优秀呢。

1.6K20
来自专栏Java开发必知必会

jdk文件bin目录中各种工具的作用(javac\javap\java\jarjstat\jvadoc等)

  -verbose                   输出有关编译器正在执行的操作的消息

31020
来自专栏Java开发必知必会

javaEE项目Multipartfile实现文件上传下载并解决上传与下载文件中文乱码的问题

里面包含了文件上传下载并解决上传与下载文件中文乱码的问题,运用正则表达式判断字符串中是否包含中文和得到一个文件夹下的所有文件的方法,几乎集合了上传下载所需要的所...

44810
来自专栏Java开发必知必会

中文编码问题详解

ASCII,ISO-8859-1,GB2312,GNBK,UTF-8,UTF-16等

41110
来自专栏SpringCloud专栏

2Java学习笔记之数据结构——双向链表

在上一篇的单链表里,数据结构是单向的,只能从前往后一个一个找,而不能倒着来。因为每个节点Node只保存了下一个节点的位置。

11320
来自专栏Java开发必知必会

Junit5系列-Junit5中DisabledCondition条件测试执行

JUnit Jupiter中的ExecutionCondition扩展API允许开发人员以编程方式启用或禁用容器或测试。 这种情况最简单的例子是内置的Disab...

16440
来自专栏Java开发必知必会

JDK8之后-JVM运行时数据区域

首先弄清几个概念: 1.方法区(method area)只是JVM规范中定义的一个概念,用于存储类信息、常量池、静态变量、JIT编译后的代码等数据,具体放在...

38220
来自专栏Java开发必知必会

JavaWeb与JavaEE命名规则(规范)

最近做的一个系统,做完之后发现命名有些不够规范,所以想要规范一下命名,这样才能使项目目录更规范与整齐,网上发现该详细的命名规范博文.但是有些命名规范已经有些不在...

64530
来自专栏SpringCloud专栏

如何复制一个java对象(浅克隆与深度克隆)

在项目中,有时候有一些比较重要的对象经常被当作参数传来传去,和C语言的值传递不同,java语言的传递都是引用传递,在任何一个...

1.6K10
来自专栏SpringCloud专栏

JEasyframe使用教程2 项目结构

   以AreaDAO为例,里面非常简单,直接extendsBaseDAO传入javabean类即可。BaseDAO里面功能很多,基本能涵盖主要的db操作方法。...

14140

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励