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

  • SMB

SMB(Server Message Block)通信协议是微软(Microsoft)和英特尔(Intel)在1987年制定的协议,主要是作为Microsoft网络的通讯协议。SMB 是在会话层(session layer)和表示层(presentation layer)以及小部分应用层(application layer)的协议。

  • 本章代码是通过配置文件把服务器IP、用户名、‘密码、下载后本地路径等信息转为可配置的XML文件,方便多服务器应用,也可把IP、用户名等信息固定在程序中

  • 点击下载源码

  • 所需jar

<!-- smb 共享文件 -->
	<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 = "ThailandSubway.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;
    }


}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值