SMB使用递归方式下载、删除远程服务器文件(包含带有子文件夹等)

简介: SMB(Server Message Block)通信协议是微软(Microsoft)和英特尔(Intel)在1987年制定的协议,主要是作为Microsoft网络的通讯协议。SMB 是在会话层(session layer)和表示层(presentation layer)以及小部分应用层(application layer)的协议。
  • 所需jar
    <dependency>
        <groupId>org.samba.jcifs</groupId>
        <artifactId>jcifs</artifactId>
        <version>1.3.3</version>
    </dependency>
<!-- Dom4j解析XML -->
    <dependency>
        <groupId>dom4j</groupId>
        <artifactId>dom4j</artifactId>
        <version>1.6.1</version>
    </dependency>
    <dependency>
        <groupId>jaxen</groupId>
        <artifactId>jaxen</artifactId>
        <version>1.1.6</version>
    </dependency>
  • xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<type>
    <smbs>
        <smb id="1" ip="192.168.6.121" username="user1" password="voicecyber@123" path="/tomcat/" localPath="F:/vcc/"   />
    </smbs>
</type>
  • XML配置文件所在目录

public class SystemConfig {

public static class FileLocation{
    public static String baseLocation="c:/voicecyber/";
}

}

  • 读取XML文件的工具类(此工具类可用于大多数XML解析)
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.*;
import java.util.*;

/**
 * @Author: YafengLiang
 * @Description:
 * @Date: Created in  11:39 2018/11/30
 */
public class XmlUtils {
    /**
     * @Description: 根据xml文件路径取得document对象
     */
    public static Document getDocument(String xmlPath) {
        if (xmlPath == null || (xmlPath.trim()).equals("")) {
            return null;
        }
        SAXReader reader = new SAXReader();
        Document document = null;
        try {
            document = reader.read(new File(xmlPath));
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return document;
    }

    /**
     * @Description: 根据document对象获取到根节点
     */
    public static Element getRootNode(Document document) {
        if (document == null) {
            return null;
        }
        Element root = document.getRootElement();
        return root;
    }

    /**
     * @Description: 根据路径直接拿到根节点
     */
    public static Element getRootNode(String xmlPath) {
        if (xmlPath == null || (xmlPath.trim()).equals("")) {
            return null;
        }
        Document document = getDocument(xmlPath);
        if (document == null) {
            return null;
        }
        return getRootNode(document);
    }


    /**
     * @Description: 得到指定元素的迭代器
     */
    public static Iterator<Element> getIterator(Element parent) {
        if (parent == null) {
            return null;
        }
        Iterator<Element> iterator = parent.elementIterator();
        return iterator;
    }

    /**
     * @Description: 根据子节点名称得到指定的子节点
     */
    public static List<Element> getChildElements(Element parent, String childName) {
        childName = childName.trim();
        if (parent == null) {
            return null;
        }
        childName = "//" + childName;
        List<Element> childElements = parent.selectNodes(childName);
        return childElements;
    }

    /**
     * @Description: getChildList
     */
    public static List<Element> getChildList(Element node) {
        if (node == null) {
            return null;
        }
        Iterator<Element> iterator = getIterator(node);
        if (iterator == null) {
            return null;
        }
        List<Element> childList = new ArrayList<Element>();
        while (iterator.hasNext()) {
            Element kidElement = iterator.next();
            if (kidElement != null) {
                childList.add(kidElement);
            }
        }
        return childList;
    }

    /**
     * @Description: 查询没有子节点的节点,使用xpath方式
     */
    public static Node getSingleNode(Element parent, String nodeName) {
        nodeName = nodeName.trim();
        String xpath = "//";
        if (parent == null) {
            return null;
        }
        if (nodeName == null || nodeName.equals("")) {
            return null;
        }
        xpath += nodeName;
        Node kid = parent.selectSingleNode(xpath);
        return kid;
    }

    /**
     * @Description: 判断节点是否还有子节点
     */
    public static boolean hasChild(Element element) {
        if (element == null) {
            return false;
        }
        return element.hasContent();
    }

    /**
     * @Description: 得到指定节点的属性的迭代器
     */
    public static Iterator<Attribute> getAttrIterator(Element element) {
        if (element == null) {
            return null;
        }
        Iterator<Attribute> attrIterator = element.attributeIterator();
        return attrIterator;
    }

    /**
     * @Description: 遍历指定节点的所有属性
     */
    public static List<Attribute> getAttributeList(Element element) {
        if (element == null) {
            return null;
        }
        List<Attribute> attributeList = new ArrayList<Attribute>();
        Iterator<Attribute> attrIterator = getAttrIterator(element);
        if (attrIterator == null) {
            return null;
        }
        while (attrIterator.hasNext()) {
            Attribute attribute = attrIterator.next();
            attributeList.add(attribute);
        }
        return attributeList;
    }

    /**
     * @Description: 得到指定节点的指定属性
     */
    public static Attribute getAttribute(Element element, String attrName) {
        attrName = attrName.trim();
        if (element == null) {
            return null;
        }
        if (attrName == null || attrName.equals("")) {
            return null;
        }
        Attribute attribute = element.attribute(attrName);
        return attribute;
    }

    /**
     * @Description: 获取指定节点指定属性的值
     */
    public static String attrValue(Element element, String attrName) {
        attrName = attrName.trim();
        if (element == null) {
            return null;
        }
        if (attrName == null || attrName.equals("")) {
            return null;
        }
        return element.attributeValue(attrName);
    }

    /**
     * @Description: 得到指定节点所有属性及属性值
     */
    public static Map<String, String> getNodeAttrMap(Element element) {
        Map<String, String> attrMap = new HashMap<String, String>();
        if (element == null) {
            return null;
        }
        List<Attribute> attributes = getAttributeList(element);
        if (attributes == null) {
            return null;
        }
        for (Attribute attribute : attributes) {
            String attrValueString = attrValue(element, attribute.getName());
            attrMap.put(attribute.getName(), attrValueString);
        }
        return attrMap;
    }

    /**
     * @Description: 根据节点名称获取text值
     */
    public static String textValue(Element element, String elementName) {
        if (elementName == null || (elementName.trim()).equals("")) {
            return null;
        }
        return element.getTextTrim();
    }

    /**
     * @Description: 节点text转换成int
     */
    public static Integer TextValueToInt(String textValue) {
        if (textValue == null || (textValue.trim()).equals("")) {
            return null;
        }
        return Integer.parseInt(textValue.trim());

    }

    /**
     * @Description: 遍历指定节点下没有子节点的元素的text值
     */
    public static Map<String, String> getStringNodeText(Element element) {
        Map<String, String> map = new HashMap<String, String>();
        if (element == null) {
            return null;
        }
        List<Element> kids = getChildList(element);
        for (Element element2 : kids) {
            if (element2.getTextTrim() != null) {
                map.put(element2.getName(), element2.getTextTrim());
            }
        }
        return map;
    }

    /**
     * @Description: 删除指定节点
     */
    public static boolean removeElemet(Element parent, String nodeName) {
        boolean flag = false;
        nodeName = nodeName.trim();
        String xpath = "";
        if (parent == null) {
            return flag;
        }
        if (nodeName == null || nodeName.equals("")) {
            return flag;
        }
        xpath += nodeName;
        List<Element> elementList = getChildElements(parent, xpath);
        if (elementList == null || elementList.size() <= 0) {
            return flag;
        }
        for (Element element : elementList) {
            element.getParent().remove(element);
            flag = true;
        }
        return flag;
    }

    /**
     * @Description: 修改节点属性值
     */
    public static void updateAttrValue(Element element, String attrName, String attrVal) {
        if (element != null && attrName.trim() != null && attrName.trim() != "") {
            Attribute attribute = element.attribute(attrName);
            if (attribute != null) {
                attribute.setValue(attrVal);
            }
        }
    }

    /**
     * @Description: 修改xml, 按路径保存
     */
    public static void saveXml(String xmlPath, Document document) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(xmlPath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        format.setExpandEmptyElements(true);
        XMLWriter writer = null;
        try {
            writer = new XMLWriter(out, format);
            writer.write(document);
            writer.close();
            out.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 工具类ApplicationConstants(XML文件名称)

/**

  • @Author: YafengLiang
  • @Description:
  • @Date: Created in 11:44 2018/11/30

*/
public interface ApplicationConstants {

interface FileName {
    String THAILAND_SUBWAY = "Thailand.xml";
}

}

  • 主要代码部分
import com.utils.ApplicationConstants;
import com.utils.SystemConfig;
import com.utils.XmlUtils;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.List;

/**
 * @Author: YafengLiang
 * @Description:
 * @Date: Created in  11:48 2018/12/7
 */
public class SmbTest {
    private static final Logger logger = LoggerFactory.getLogger(SmbTest.class);

    public static void main(String[] args) {
        MyRun myRun = new MyRun();
        new Thread(myRun).start();
    }

    /**
     * 实时同步共享目录文件到本地
     */
    public static class MyRun implements Runnable {

        @Override
        public void run() {
            String rootFile = SystemConfig.FileLocation.baseLocation+ ApplicationConstants.FileName.THAILAND_SUBWAY;
            Element rootElement = XmlUtils.getRootNode(rootFile);
            List<Element> list = XmlUtils.getChildElements(rootElement,"smb");
            String id1 = "1";
            if (list.size()>0){
                for (Element element : list) {
                    String ids = element.attributeValue("id");
                    if (id1.equals(ids)){
                        String HOST = element.attributeValue("ip");
                        String USERNAME = element.attributeValue("username");
                        String PASSWORD = element.attributeValue("password");
                        String PATH = element.attributeValue("path");
                        String LOCAL_DIRECTORY = element.attributeValue("localPath");
                        String URL = "smb://"+HOST+PATH;
                        while (true) {
                            try {
                                logger.info("十秒后开始。。。。。。");
                                Thread.sleep(10 * 1000);
                                logger.info("继续。。。。。。");
                                getRemoteFile(URL,USERNAME,PASSWORD,LOCAL_DIRECTORY,HOST);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

            }
        }
    }

    /**
     * 获取远程文件
     * @param remoteUsername 远程目录访问用户名
     * @param remotePassword 远程目录访问密码
     * @param url 远程文件地址,该参数需以IP打头,如'192.168.6.121/aa/bb.java'或者'192.168.6.121/aa/',如'192.168.6.121/aa'是不对的
     * @param localDirectory 本地存储目录,该参数需以'/'结尾,如'D:/'或者'D:/mylocal/'
     * @return boolean 是否获取成功
     * @throws Exception
     */
    public static boolean getRemoteFile(String url,String remoteUsername, String remotePassword,
                                        String localDirectory,String HOST) throws Exception {
        boolean isSuccess = Boolean.FALSE;
        if (url.startsWith("/") || url.startsWith("\\")) {
            return isSuccess;
        }
        if (!(localDirectory.endsWith("/") || localDirectory.endsWith("\\"))) {
            return isSuccess;
        }
        NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(HOST,remoteUsername,remotePassword);
        SmbFile smbFile = new SmbFile(url, auth);
        if (smbFile != null) {
            if (smbFile.isDirectory()) {
                SmbFile[] smbFiles = smbFile.listFiles();
                for (SmbFile file : smbFiles) {
                    File file1 = new File(localDirectory+File.separator+file.getName());
                    if (smbFile.isDirectory()) {
                        getRemoteFile(url + File.separator + file.getName(), remoteUsername, remotePassword, localDirectory + File.separator + file.getName(),HOST);
                        if (!file1.exists()) {
                            isSuccess = copyFile(file, localDirectory);

                        }else {
                            logger.info("已存在 "+file1);
                            String smbUrl =  url + File.separator + file.getName();
                            String str = smbUrl.replace("\\\\","");
                            SmbFile smbFile1 = new SmbFile(str,auth);
                            smbFile1.delete();
                            logger.info("删除:"+smbUrl.replace("\\\\","")+" 成功");
                        }
                    }else {
                        isSuccess = copyFile(file, localDirectory);
                    }
                }
            } else if (smbFile.isFile()) {
                isSuccess = copyFile(smbFile, localDirectory);
            }
        }

            return isSuccess;
    }


    /**
     * 拷贝远程文件到本地目录
     * @param smbFile 远程SmbFile
     * @param localDirectory 本地存储目录,本地目录不存在时会自动创建,本地目录存在时可自行选择是否清空该目录下的文件,默认为不清空
     * @return boolean 是否拷贝成功
     */
    public static boolean copyFile(SmbFile smbFile, String localDirectory) {
        SmbFileInputStream in = null;
        FileOutputStream out = null;
        try {
            File[] localFiles = new File(localDirectory).listFiles();
            if (null == localFiles) {
                // 目录不存在的话,就创建目录
                new File(localDirectory).mkdirs();
                logger.info(localDirectory+"目录创建成功!");
            }
            in = new SmbFileInputStream(smbFile);
            out = new FileOutputStream(localDirectory + smbFile.getName());
            byte[] buffer = new byte[4096];
            int len = -1;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
                buffer = new byte[4096];
            }
            out.flush();
            logger.info("拷贝 "+smbFile.getName()+" 成功");
        } catch (Exception e) {
            logger.error("拷贝远程文件到本地目录失败", e);
            return false;
        } finally {
            if (null != out) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }
}
目录
相关文章
|
28天前
|
存储 弹性计算 数据可视化
要将ECS中的文件直接传输到阿里云网盘与相册(
【2月更文挑战第31天】要将ECS中的文件直接传输到阿里云网盘与相册(
415 4
|
2月前
|
数据可视化 Shell Linux
shell+crontab+gitlab实现ecs服务器文件的web展示
本文通过把ecs服务器上的文件定时上传至gitlab,实现文件的页面可视化和修改历史。技术点:shell、crontab、gitlab。
50 3
|
1月前
|
缓存 网络协议 数据可视化
WinSCP下载安装并实现远程SSH本地服务器上传文件
WinSCP下载安装并实现远程SSH本地服务器上传文件
|
3月前
|
弹性计算 数据可视化 安全
云服务器ECS里文件的URL,如何查到呢?
云服务器ECS里文件的URL,如何查到呢?
52 0
|
28天前
|
Linux Shell 网络安全
【Shell 命令集合 网络通讯 】Linux 与SMB服务器进行交互 smbclient命令 使用指南
【Shell 命令集合 网络通讯 】Linux 与SMB服务器进行交互 smbclient命令 使用指南
40 1
|
1月前
|
Linux 网络安全 Python
如何在服务器上运行python文件
如何在服务器上运行python文件
|
25天前
|
安全 数据处理 C#
C# Post数据或文件到指定的服务器进行接收
C# Post数据或文件到指定的服务器进行接收
|
1月前
|
数据可视化 网络安全 Windows
下载安装MobaXterm并链接服务器的操作方法
【2月更文挑战第13天】本文介绍在Windows电脑中,下载、配置MobaXterm软件,从而连接、操作远程服务器的方法~
下载安装MobaXterm并链接服务器的操作方法
|
2月前
|
Java
java上传、下载、预览、删除ftp服务器上的文件
java上传、下载、预览、删除ftp服务器上的文件
|
2月前
|
Linux
本地下载使用证书登陆的linux服务器的文件的命令
本地下载使用证书登陆的linux服务器的文件的命令

热门文章

最新文章