用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();
    }
}

扩展阅读


posted @ 2019-01-29 17:39  叉叉敌  阅读(399)  评论(0编辑  收藏  举报