• 在Java程序中读写windows共享文件夹


    摘要 使用Java通过JCIFS框架读写共享文件夹,使用SMB协议,并支持域认证。

    项目常常需要有访问共享文件夹的需求,例如读取共享文件夹存储的视频、照片和PPT等文件。那么如何使用Java读写Windows共享文件夹呢?

    使用Java访问拥有全部读写权限的共享文件夹比较简单,和普通的目录没有什么区别。但是,如果从Linux服务器访问一个windows服务器上需要用户名和密码验证的共享文件夹,就需要一点点小技巧了。这里介绍一个开源的库JCIFS,他可以轻松满足此需求。

    JCIFS是使用Java语言开发的一款开源框架,通过SMB协议访问远程共享文件夹,就像访问本地文件夹一样,简简单单。她同时支持Windows和Linux共享文件夹,不过,Linux共享文件夹需要安装Samba服务软件(官网:http://www.samba.org/)。

    另外,通过挂载该共享文件夹到Linux服务器下也可以实现,此时不需要借助SMB协议,对此,这里不做介绍,感兴趣的童鞋可以去问问度娘。

    言归正传,maven依赖如下:

    <!-- https://mvnrepository.com/artifact/org.samba.jcifs/jcifs -->
    <dependency>
        <groupId>org.samba.jcifs</groupId>
        <artifactId>jcifs</artifactId>
        <version>1.3.3</version>
    </dependency>

    SMB(Server Message Block)通信协议是微软(Microsoft)和英特尔(Intel)在1987年制定的协议,主要是作为Microsoft网络的通讯协议。SMB 是在会话层(session layer)和表示层(presentation layer)以及小部分应用层(application layer)的协议。通过设置“NetBIOS over TCP/IP”使得Samba不但能与局域网络主机分享资源,还能与全世界的电脑分享资源。

    代码示例:

     
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import jcifs.smb.NtlmPasswordAuthentication;
    import jcifs.smb.SmbFile;
    import jcifs.smb.SmbFileInputStream;
    import jcifs.smb.SmbFileOutputStream;
    
    public class SmbFileUtil {
    
        private static Logger log = LoggerFactory.getLogger(SmbFileUtil.class);
    
        private static String USER_DOMAIN = "yourDomain";
        private static String USER_ACCOUNT = "yourAccount";
        private static String USER_PWS = "yourPassword";
    
        public static void main(String[] args) throws Exception {
    
            // remoteUrl 格式示例 【smb://132.20.2.33/CIMPublicTest/】
            // 目录
            String shareDir = "smb:// 132.20.2.33/CIMPublicTest/";
            listFiles(shareDir);
            
        }
    
        /**
         * @Title listFiles
         * @Description 遍历指定目录下的文件
         * @date 2019-01-11 09:56
         */
        private static void listFiles(String shareDirectory) throws Exception {
            long startTime = System.currentTimeMillis();
    
            // 域服务器验证
            NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(USER_DOMAIN, USER_ACCOUNT,
                    USER_PWS);
            SmbFile remoteFile = new SmbFile(shareDirectory, auth);
            log.info("远程共享目录访问耗时:【{}】", System.currentTimeMillis() - startTime);
    
            if (remoteFile.exists()) {
                SmbFile[] files = remoteFile.listFiles();
                remoteFile.listFiles(shareDirectory);
                
                for (SmbFile f : files) {
                    log.info(f.getName());
                }
            } else {
                log.info("文件不存在");
            }
        }
    }
     

    NtlmPasswordAuthentication类用于域认证,需要三个参数, 第一个是域名,如果没有,就赋值null, 第二个是用户名,第三个是密码。下面列举SMB协议的两个应用场景。SmbFile类和Java的File类十分相似,使用其对象可以处理远程共享文件的读写。

     
        /**
         * @Title smbGet
         * @Param shareUrl 共享目录中的文件路径,如smb://132.20.2.33/CIMPublicTest/eg.txt
         * @Param localDirectory 本地目录,如tempStore/smb
         */
        public static void smbGet(String shareUrl, String localDirectory) throws Exception {
            NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(USER_DOMAIN, USER_ACCOUNT,
                    USER_PWS);
            SmbFile remoteFile = new SmbFile(shareUrl, auth);
            if (!remoteFile.exists()) {
                log.info("共享文件不存在");
                return;
            }
            // 有文件的时候再初始化输入输出流
            InputStream in = null;
            OutputStream out = null;
            log.info("下载共享目录的文件 shareUrl 到 localDirectory");
            try {
                String fileName = remoteFile.getName();
                File localFile = new File(localDirectory + File.separator + fileName);
                File fileParent = localFile.getParentFile();
                if (null != fileParent && !fileParent.exists()) {
                    fileParent.mkdirs();
                }
                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];
                }
                out.flush(); //刷新缓冲区输出流
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                out.close();
                in.close();
            }
        }
    
        /**
         * 
         * @Title smbPut
         * @Description 向共享目录上传文件
         * @Param shareDirectory 共享目录
         * @Param localFilePath 本地目录中的文件路径
         * @date 2019-01-10 20:16
         */
        public static void smbPut(String shareDirectory, String localFilePath) {
            InputStream in = null;
            OutputStream out = null;
            try {
                File localFile = new File(localFilePath);
    
                String fileName = localFile.getName();
                SmbFile remoteFile = new SmbFile(shareDirectory + "/" + fileName);
                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];
                }
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    out.close();
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    优秀不够,你是否无可替代

    软件测试交流QQ群:721256703,期待你的加入!!

    欢迎关注我的微信公众号:软件测试君


  • 相关阅读:
    [Codeforces Round #516][Codeforces 1063C/1064E. Dwarves, Hats and Extrasensory Abilities]
    接入gitment为hexo添加评论功能
    常用SQL语句
    小米前端二面面经
    将hexo的评论系统由gitment改为Valine
    同步与异步
    前端构建工具对比
    前端向后台发送请求有哪些方式
    关于hexo markdown添加的图片在github page中无法显示的问题
    使用TensorBoard可视化工具
  • 原文地址:https://www.cnblogs.com/longronglang/p/13594033.html
Copyright © 2020-2023  润新知