zoukankan      html  css  js  c++  java
  • 在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,期待你的加入!!

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


  • 相关阅读:
    Linux IO接口 监控 (iostat)
    linux 防火墙 命令
    _CommandPtr 添加参数 0xC0000005: Access violation writing location 0xcccccccc 错误
    Visual Studio自动关闭
    Linux vsftpd 安装 配置
    linux 挂载外部存储设备 (mount)
    myeclipse 9.0 激活 for win7 redhat mac 亲测
    英文操作系统 Myeclipse Console 乱码问题
    Linux 基本操作命令
    linux 查看系统相关 命令
  • 原文地址:https://www.cnblogs.com/longronglang/p/13594033.html
Copyright © 2011-2022 走看看