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;
    }
}
目录
相关文章
|
2月前
|
存储 UED Windows
Windows服务器上大量文件迁移方案
Windows服务器上大量文件迁移方案
140 1
|
3月前
|
存储 监控 固态存储
【vSAN分布式存储服务器数据恢复】VMware vSphere vSAN 分布式存储虚拟化平台VMDK文件1KB问题数据恢复案例
在一例vSAN分布式存储故障中,因替换故障闪存盘后磁盘组失效,一台采用RAID0策略且未使用置备的虚拟机VMDK文件受损,仅余1KB大小。经分析发现,该VMDK文件与内部虚拟对象关联失效导致。恢复方案包括定位虚拟对象及组件的具体物理位置,解析分配空间,并手动重组RAID0结构以恢复数据。此案例强调了深入理解vSAN分布式存储机制的重要性,以及定制化数据恢复方案的有效性。
94 5
|
1月前
|
IDE 网络安全 开发工具
IDE之vscode:连接远程服务器代码(亲测OK),与pycharm链接服务器做对比(亲自使用过了),打开文件夹后切换文件夹。
本文介绍了如何使用VS Code通过Remote-SSH插件连接远程服务器进行代码开发,并与PyCharm进行了对比。作者认为VS Code在连接和配置多个服务器时更为简单,推荐使用VS Code。文章详细说明了VS Code的安装、远程插件安装、SSH配置文件编写、服务器连接以及如何在连接后切换文件夹。此外,还提供了使用密钥进行免密登录的方法和解决权限问题的步骤。
381 0
IDE之vscode:连接远程服务器代码(亲测OK),与pycharm链接服务器做对比(亲自使用过了),打开文件夹后切换文件夹。
|
1月前
|
Python
Flask学习笔记(三):基于Flask框架上传特征值(相关数据)到服务器端并保存为txt文件
这篇博客文章是关于如何使用Flask框架上传特征值数据到服务器端,并将其保存为txt文件的教程。
31 0
Flask学习笔记(三):基于Flask框架上传特征值(相关数据)到服务器端并保存为txt文件
|
1月前
阿里云国际版购买了服务器后如何下载发票?
阿里云国际版购买了服务器后如何下载发票?
|
2月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
54 4
|
29天前
|
前端开发 Docker 容器
主机host服务器和Docker容器之间的文件互传方法汇总
Docker 成为前端工具,可实现跨设备兼容。本文介绍主机与 Docker 容器/镜像间文件传输的三种方法:1. 构建镜像时使用 `COPY` 或 `ADD` 指令;2. 启动容器时使用 `-v` 挂载卷;3. 运行时使用 `docker cp` 命令。每种方法适用于不同场景,如静态文件打包、开发时文件同步及临时文件传输。注意权限问题、容器停止后的文件传输及性能影响。
128 0
|
3月前
|
Linux
Linux 服务器下载百度网盘文件
本教程指导如何使用 `bypy` 库从百度网盘下载文件。首先通过 `pip install bypy` 安装库,接着运行 `bypy info` 获取登录链接并完成授权,最后将文件置于指定目录并通过 `bypy downdir /Ziya-13b-v1` 命令下载至本地。
337 1
Linux 服务器下载百度网盘文件
|
3月前
|
存储 安全 文件存储
【服务器数据恢复】Apple苹果Xsan文件系统卷宗误操作导致文件丢失数据恢复案例
客户因误操作删除了macOS服务器上的重要图片和视频文件,需紧急恢复。Xsan文件系统作为苹果专为高负载环境设计的64位簇文件系统,在未有专门恢复工具的情况下,常规RAW恢复仅能提取小部分连续存储的小文件,且无目录结构。通过专业的数据恢复流程,包括安全挂载、阵列重组,并使用专用工具解析文件系统以恢复目录结构,最终成功恢复丢失的文件。此案例突显了Xsan文件系统的特点及其恢复难度。
37 1
|
3月前
|
数据可视化 Python
通过python建立一个web服务查看服务器上的文本、图片、视频等文件
通过python建立一个web服务查看服务器上的文本、图片、视频等文件
68 0