精华内容
下载资源
问答
  • ftp工具

    2017-10-17 19:11:38
    记录一个在项目中用到的ftp工具1.ftp概述  FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文件传输协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序...

    记录一个在项目中用到的ftp工具

    1.ftp概述

      FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文件传输协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。–摘自百度
      也就是说“ftp”是一种协议,用来在网络中传输文件,基于这种协议可以有一种应用:就是将文件从A处传输到B处,传输的过程是通过ftp协议完成的。
      实际的使用场景是这样的,会存在一个东西叫做FTP服务端,同时存在另一个东西叫做FTP客户端,显而易见,客户端与服务器端建立连接后,客户端可以向服务器端上传或下载文件,也可以进行一些其他操作,例如新建一个文件夹,或者删除一个文件。好啦,再举一个生动的例子:某人在上海出差,要向北京总部传一个word文件,于是他想到了使用ftp方式,打开他的电脑,再打开FTP客户端工具(本人使用FileZilla),连接到总部的FTP服务器,然后点击上传按钮,文件就上传了,于此同时他发现总部的FTP服务器中有最近上映的新电影(枪版),果断下载,看之,愉快的周末结束了。这大概就是一般情况下ftp的应用场景了。所以,这里面有两个概念很重要:FTP服务端,FTP客户端。
      windows系统下有许多FTP应用工具(本人使用FileZilla),使用这些工具可以很轻松的完成上述场景,但这不是本文讨论的重点,本文讨论的在java程序中如何对FTP服务端进行文件操作。

    2.sftp概念

      这里还需要提一下sftp的概念:sftp是Secure File Transfer Protocol的缩写,安全文件传送协议。可以为传输文件提供一种安全的网络的加密方法。sftp 与 ftp 有着几乎一样的语法和功能。SFTP 为 SSH的其中一部分,是一种传输档案至 Blogger 伺服器的安全方式。–同样摘自百度。姑且就理解为一种比ftp更安全一点的协议吧。在windows下使用工具实现操作与ftp一样,本次代码实现同样需要考虑。

    3.代码部分

      这段代码是在项目中抽象出来的一个工具类,形式为一个接口和两个实现类,接口定义了相关的文件操作方法,实现类分别是ftp的实现和sftp的实现。如下:

    代码结构:

    1. IFtpHelper(ftp接口)
    2. SftpHelperImpl(sftp实现)
    3. StandardFtpHelperImpl(ftp实现)

    具体代码:

    IFtpHelper:

        import java.io.OutputStream;
        import java.util.Set;
    
        public interface IFtpHelper {
    
    /**
     * 登陆ftp服务器(使用被动方式)
     * @param host
     * @param username
     * @param password
     * @param port
     * @param timeout
     */
    public void loginFtpServer(String host, String username, String password, int port, int timeout);
    
    /**
     *注销登陆
     */
    public void logoutFtpServer();
    
    /**
     * 创建目录(warn: 不支持递归创建)
     * @param directoryPath
     */
    public void mkdir(String directoryPath);
    
    /**
     * 递归创建目录
     * @param directoryPath
     */
    public void mkDirRecursive(String directoryPath);
    
    /**
     * 根据ftp服务器上指定目录下的文件名,获得其输出流
     * @param filePath
     * @return
     */
    public OutputStream getOutputStream(String filePath);
    
    public String getRemoteFileContent(String filePath);
    
    public Set<String> getAllFilesInDir(String dir, String prefixFileName);
    
    /**
     * 删除文件(不支持删除文件夹)
     * @param filesToDelete
     */
    public void deleteFiles(Set<String> filesToDelete);
    
    public void completePendingCommand();
    
    /**
     * 向ftp目录中写入文件
     * @param sourceFilePath
     * @param targetFilePath
     */
    public void localWriteToFtp(String sourceFilePath,String targetFilePath);
    
    }
    

    SftpHelperImpl:

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.serializer.SerializerFeature;
    import com.chinawiserv.dsp.dcs.dc.common.exception.DataXException;
    import com.jcraft.jsch.*;
    import com.jcraft.jsch.ChannelSftp.LsEntry;
    import org.apache.commons.io.IOUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.commons.net.ftp.FTP;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.io.*;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.HashSet;
    import java.util.Properties;
    import java.util.Set;
    import java.util.Vector;
    
    public class SftpHelperImpl implements IFtpHelper {
    private static final Logger LOG = LoggerFactory
            .getLogger(SftpHelperImpl.class);
    
    private Session session = null;
    private ChannelSftp channelSftp = null;
    
    @Override
    public void loginFtpServer(String host, String username, String password,
                               int port, int timeout) {
        JSch jsch = new JSch();
        try {
            this.session = jsch.getSession(username, host, port);
            if (this.session == null) {
                throw DataXException
                        .asDataXException(FtpWriterErrorCode.FAIL_LOGIN,
                                "创建ftp连接this.session失败,无法通过sftp与服务器建立链接,请检查主机名和用户名是否正确.");
            }
    
            this.session.setPassword(password);
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            // config.put("PreferredAuthentications", "password");
            this.session.setConfig(config);
            this.session.setTimeout(timeout);
            this.session.connect();
    
            this.channelSftp = (ChannelSftp) this.session.openChannel("sftp");
            this.channelSftp.connect();
        } catch (JSchException e) {
            if (null != e.getCause()) {
                String cause = e.getCause().toString();
                String unknownHostException = "java.net.UnknownHostException: "
                        + host;
                String illegalArgumentException = "java.lang.IllegalArgumentException: port out of range:"
                        + port;
                String wrongPort = "java.net.ConnectException: Connection refused";
                if (unknownHostException.equals(cause)) {
                    String message = String
                            .format("请确认ftp服务器地址是否正确,无法连接到地址为: [%s] 的ftp服务器, errorMessage:%s",
                                    host, e.getMessage());
                    LOG.error(message);
                    throw DataXException.asDataXException(
                            FtpWriterErrorCode.FAIL_LOGIN, message, e);
                } else if (illegalArgumentException.equals(cause)
                        || wrongPort.equals(cause)) {
                    String message = String.format(
                            "请确认连接ftp服务器端口是否正确,错误的端口: [%s], errorMessage:%s",
                            port, e.getMessage());
                    LOG.error(message);
                    throw DataXException.asDataXException(
                            FtpWriterErrorCode.FAIL_LOGIN, message, e);
                }
            } else {
                String message = String
                        .format("与ftp服务器建立连接失败,请检查主机、用户名、密码是否正确, host:%s, port:%s, username:%s, errorMessage:%s",
                                host, port, username, e.getMessage());
                LOG.error(message);
                throw DataXException.asDataXException(
                        FtpWriterErrorCode.FAIL_LOGIN, message);
            }
        }
    
    }
    
    @Override
    public void logoutFtpServer() {
        if (this.channelSftp != null) {
            this.channelSftp.disconnect();
            this.channelSftp = null;
        }
        if (this.session != null) {
            this.session.disconnect();
            this.session = null;
        }
    }
    
    @Override
    public void mkdir(String directoryPath) {
        boolean isDirExist = false;
        try {
            this.printWorkingDirectory();
            SftpATTRS sftpATTRS = this.channelSftp.lstat(directoryPath);
            isDirExist = sftpATTRS.isDir();
        } catch (SftpException e) {
            if (e.getMessage().toLowerCase().equals("no such file")) {
                LOG.warn(String.format(
                        "您的配置项path:[%s]不存在,将尝试进行目录创建, errorMessage:%s",
                        directoryPath, e.getMessage()), e);
                isDirExist = false;
            }
        }
        if (!isDirExist) {
            try {
                // warn 检查mkdir -p
                this.channelSftp.mkdir(directoryPath);
            } catch (SftpException e) {
                String message = String
                        .format("创建目录:%s时发生I/O异常,请确认与ftp服务器的连接正常,拥有目录创建权限, errorMessage:%s",
                                directoryPath, e.getMessage());
                LOG.error(message, e);
                throw DataXException
                        .asDataXException(
                                FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION,
                                message, e);
            }
        }
    }
    
    @Override
    public void mkDirRecursive(String directoryPath){
        boolean isDirExist = false;
        try {
            this.printWorkingDirectory();
            SftpATTRS sftpATTRS = this.channelSftp.lstat(directoryPath);
            isDirExist = sftpATTRS.isDir();
        } catch (SftpException e) {
            if (e.getMessage().toLowerCase().equals("no such file")) {
                LOG.warn(String.format(
                        "您的配置项path:[%s]不存在,将尝试进行目录创建, errorMessage:%s",
                        directoryPath, e.getMessage()), e);
                isDirExist = false;
            }
        }
        if (!isDirExist) {
            StringBuilder dirPath = new StringBuilder();
            dirPath.append(IOUtils.DIR_SEPARATOR_UNIX);
            String[] dirSplit = StringUtils.split(directoryPath, IOUtils.DIR_SEPARATOR_UNIX);
            try {
                // ftp server不支持递归创建目录,只能一级一级创建
                for(String dirName : dirSplit){
                    dirPath.append(dirName);
                    mkDirSingleHierarchy(dirPath.toString());
                    dirPath.append(IOUtils.DIR_SEPARATOR_UNIX);
                }
            } catch (SftpException e) {
                String message = String
                        .format("创建目录:%s时发生I/O异常,请确认与ftp服务器的连接正常,拥有目录创建权限, errorMessage:%s",
                                directoryPath, e.getMessage());
                LOG.error(message, e);
                throw DataXException
                        .asDataXException(
                                FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION,
                                message, e);
            }
        }
    }
    
    public boolean mkDirSingleHierarchy(String directoryPath) throws SftpException {
        boolean isDirExist = false;
        try {
            SftpATTRS sftpATTRS = this.channelSftp.lstat(directoryPath);
            isDirExist = sftpATTRS.isDir();
        } catch (SftpException e) {
            if(!isDirExist){
                LOG.info(String.format("正在逐级创建目录 [%s]",directoryPath));
                this.channelSftp.mkdir(directoryPath);
                return true;
            }
        }
        if(!isDirExist){
            LOG.info(String.format("正在逐级创建目录 [%s]",directoryPath));
            this.channelSftp.mkdir(directoryPath);
        }
        return true;
    }
    
    @Override
    public OutputStream getOutputStream(String filePath) {
        try {
            this.printWorkingDirectory();
            String parentDir = filePath.substring(0,
                    StringUtils.lastIndexOf(filePath, IOUtils.DIR_SEPARATOR));
            this.channelSftp.cd(parentDir);
            this.printWorkingDirectory();
            //对文件名进行拆分
            String fileName = filePath.substring(filePath.lastIndexOf(File.separator)+1);
            OutputStream writeOutputStream = this.channelSftp.put(fileName,
                    ChannelSftp.APPEND);
            String message = String.format(
                    "打开FTP文件[%s]获取写出流时出错,请确认文件%s有权限创建,有权限写出等", filePath,
                    filePath);
            if (null == writeOutputStream) {
                throw DataXException.asDataXException(
                        FtpWriterErrorCode.OPEN_FILE_ERROR, message);
            }
            return writeOutputStream;
        } catch (SftpException e) {
            String message = String.format(
                    "写出文件[%s] 时出错,请确认文件%s有权限写出, errorMessage:%s", filePath,
                    filePath, e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.OPEN_FILE_ERROR, message);
        }
    }
    
    @Override
    public String getRemoteFileContent(String filePath) {
        try {
            this.completePendingCommand();
            this.printWorkingDirectory();
            String parentDir = filePath.substring(0,
                    StringUtils.lastIndexOf(filePath, IOUtils.DIR_SEPARATOR));
            this.channelSftp.cd(parentDir);
            this.printWorkingDirectory();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream(22);
            this.channelSftp.get(filePath, outputStream);
            String result = outputStream.toString();
            IOUtils.closeQuietly(outputStream);
            return result;
        } catch (SftpException e) {
            String message = String.format(
                    "写出文件[%s] 时出错,请确认文件%s有权限写出, errorMessage:%s", filePath,
                    filePath, e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.OPEN_FILE_ERROR, message);
        }
    }
    
    @Override
    public Set<String> getAllFilesInDir(String dir, String prefixFileName) {
        Set<String> allFilesWithPointedPrefix = new HashSet<String>();
        try {
            this.printWorkingDirectory();
            @SuppressWarnings("rawtypes")
            Vector allFiles = this.channelSftp.ls(dir);
            LOG.debug(String.format("ls: %s", JSON.toJSONString(allFiles,
                    SerializerFeature.UseSingleQuotes)));
            for (int i = 0; i < allFiles.size(); i++) {
                LsEntry le = (LsEntry) allFiles.get(i);
                String strName = le.getFilename();
                if (strName.startsWith(prefixFileName)) {
                    allFilesWithPointedPrefix.add(strName);
                }
            }
        } catch (SftpException e) {
            String message = String
                    .format("获取path:[%s] 下文件列表时发生I/O异常,请确认与ftp服务器的连接正常,拥有目录ls权限, errorMessage:%s",
                            dir, e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION, message, e);
        }
        return allFilesWithPointedPrefix;
    }
    
    @Override
    public void deleteFiles(Set<String> filesToDelete) {
        String eachFile = null;
        try {
            this.printWorkingDirectory();
            for (String each : filesToDelete) {
                LOG.info(String.format("delete file [%s].", each));
                eachFile = each;
                this.channelSftp.rm(each);
            }
        } catch (SftpException e) {
            String message = String.format(
                    "删除文件:[%s] 时发生异常,请确认指定文件有删除权限,以及网络交互正常, errorMessage:%s",
                    eachFile, e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION, message, e);
        }
    }
    
    private void printWorkingDirectory() {
        try {
            LOG.info(String.format("current working directory:%s",
                    this.channelSftp.pwd()));
        } catch (Exception e) {
            LOG.warn(String.format("printWorkingDirectory error:%s",
                    e.getMessage()));
        }
    }
    
    @Override
    public void completePendingCommand() {
    }
    
    /**
     * 向ftp目录中写入文件
     * @param sourceFilePath
     * @param targetFilePath
     */
    @Override
    public void localWriteToFtp(String sourceFilePath,String targetFilePath){
        try(BufferedOutputStream bos = new BufferedOutputStream( this.getOutputStream(targetFilePath));
        ) {
            Files.copy(Paths.get(sourceFilePath),bos);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    }
    

    StandardFtpHelperImpl:

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.serializer.SerializerFeature;
    import com.chinawiserv.dsp.dcs.dc.common.exception.DataXException;
    import org.apache.commons.io.IOUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPFile;
    import org.apache.commons.net.ftp.FTPReply;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.io.*;
    import java.net.UnknownHostException;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.HashSet;
    import java.util.Set;
    

    public class StandardFtpHelperImpl implements IFtpHelper {
    private static final Logger LOG = LoggerFactory
    .getLogger(StandardFtpHelperImpl.class);
    FTPClient ftpClient = null;

    @Override
    public void loginFtpServer(String host, String username, String password,
                               int port, int timeout) {
        this.ftpClient = new FTPClient();
        try {
    

    // this.ftpClient.setControlEncoding(“UTF-8”);
    // 不需要写死ftp server的OS TYPE,FTPClient getSystemType()方法会自动识别
    // this.ftpClient.configure(new FTPClientConfig(FTPClientConfig.SYST_UNIX));
    this.ftpClient.setDefaultTimeout(timeout);
    this.ftpClient.setConnectTimeout(timeout);
    this.ftpClient.setDataTimeout(timeout);

            // 连接登录
            this.ftpClient.connect(host, port);
            this.ftpClient.login(username, password);
    
            this.ftpClient.enterRemotePassiveMode();
            this.ftpClient.enterLocalPassiveMode();
            int reply = this.ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                this.ftpClient.disconnect();
                String message = String
                        .format("与ftp服务器建立连接失败,host:%s, port:%s, username:%s, replyCode:%s",
                                host, port, username, reply);
                LOG.error(message);
                throw DataXException.asDataXException(
                        FtpWriterErrorCode.FAIL_LOGIN, message);
            }
            String fileEncoding = "GBK";
            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
                    "OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
                fileEncoding = "UTF-8";
            }
            this.ftpClient.setControlEncoding(fileEncoding);
        } catch (UnknownHostException e) {
            String message = String.format(
                    "请确认ftp服务器地址是否正确,无法连接到地址为: [%s] 的ftp服务器, errorMessage:%s",
                    host, e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.FAIL_LOGIN, message, e);
        } catch (IllegalArgumentException e) {
            String message = String.format(
                    "请确认连接ftp服务器端口是否正确,错误的端口: [%s], errorMessage:%s", port,
                    e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.FAIL_LOGIN, message, e);
        } catch (Exception e) {
            String message = String
                    .format("与ftp服务器建立连接失败,host:%s, port:%s, username:%s, errorMessage:%s",
                            host, port, username, e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.FAIL_LOGIN, message, e);
        }
    
    }
    
    @Override
    public void logoutFtpServer() {
        if (this.ftpClient.isConnected()) {
            try {
                this.ftpClient.logout();
            } catch (IOException e) {
                String message = String.format(
                        "与ftp服务器断开连接失败, errorMessage:%s", e.getMessage());
                LOG.error(message);
                throw DataXException.asDataXException(
                        FtpWriterErrorCode.FAIL_DISCONNECT, message, e);
            } finally {
                if (this.ftpClient.isConnected()) {
                    try {
                        this.ftpClient.disconnect();
                    } catch (IOException e) {
                        String message = String.format(
                                "与ftp服务器断开连接失败, errorMessage:%s",
                                e.getMessage());
                        LOG.error(message);
                        throw DataXException.asDataXException(
                                FtpWriterErrorCode.FAIL_DISCONNECT, message, e);
                    }
                }
                this.ftpClient = null;
            }
        }
    }
    
    @Override
    public void mkdir(String directoryPath) {
        String message = String.format("创建目录:%s时发生异常,请确认与ftp服务器的连接正常,拥有目录创建权限",
                directoryPath);
        try {
            this.printWorkingDirectory();
            boolean isDirExist = this.ftpClient
                    .changeWorkingDirectory(directoryPath);
            if (!isDirExist) {
                int replayCode = this.ftpClient.mkd(directoryPath);
                message = String
                        .format("%s,replayCode:%s", message, replayCode);
                if (replayCode != FTPReply.COMMAND_OK
                        && replayCode != FTPReply.PATHNAME_CREATED) {
                    throw DataXException.asDataXException(
                            FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION,
                            message);
                }
            }
        } catch (IOException e) {
            message = String.format("%s, errorMessage:%s", message,
                    e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION, message, e);
        }
    }
    
    @Override
    public void mkDirRecursive(String directoryPath){
        StringBuilder dirPath = new StringBuilder();
        dirPath.append(IOUtils.DIR_SEPARATOR_UNIX);
        String[] dirSplit = StringUtils.split(directoryPath, IOUtils.DIR_SEPARATOR_UNIX);
        String message = String.format("创建目录:%s时发生异常,请确认与ftp服务器的连接正常,拥有目录创建权限", directoryPath);
        try {
            // ftp server不支持递归创建目录,只能一级一级创建
            for(String dirName : dirSplit){
                dirPath.append(dirName);
                boolean mkdirSuccess = mkDirSingleHierarchy(dirPath.toString());
                dirPath.append(IOUtils.DIR_SEPARATOR_UNIX);
                if(!mkdirSuccess){
                    throw DataXException.asDataXException(
                            FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION,
                            message);
                }
            }
        } catch (IOException e) {
            message = String.format("%s, errorMessage:%s", message,
                    e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION, message, e);
        }
    }
    
    public boolean mkDirSingleHierarchy(String directoryPath) throws IOException {
        boolean isDirExist = this.ftpClient
                .changeWorkingDirectory(directoryPath);
        // 如果directoryPath目录不存在,则创建
        if (!isDirExist) {
            int replayCode = this.ftpClient.mkd(directoryPath);
            if (replayCode != FTPReply.COMMAND_OK
                    && replayCode != FTPReply.PATHNAME_CREATED) {
                return false;
            }
        }
        return true;
    }
    
    @Override
    public OutputStream getOutputStream(String filePath) {
        try {
            this.printWorkingDirectory();
            String parentDir = filePath.substring(0,
                    StringUtils.lastIndexOf(filePath, IOUtils.DIR_SEPARATOR));
            this.ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            boolean flage = this.ftpClient.changeWorkingDirectory(parentDir);
            if(!flage){
                String message = String.format("请确认您的配置项path:[%s]存在,且配置的用户有权限进入", parentDir);
                LOG.error(message);
                throw DataXException.asDataXException(FtpWriterErrorCode.FILE_NOT_EXISTS, message);
            }
            this.printWorkingDirectory();
            OutputStream writeOutputStream = this.ftpClient
                    .appendFileStream(new String(filePath.getBytes(), FTP.DEFAULT_CONTROL_ENCODING));
            String message = String.format(
                    "打开FTP文件[%s]获取写出流时出错,请确认文件%s有权限创建,有权限写出等", filePath,
                    filePath);
            if (null == writeOutputStream) {
                throw DataXException.asDataXException(
                        FtpWriterErrorCode.OPEN_FILE_ERROR, message);
            }
    
            return writeOutputStream;
        } catch (IOException e) {
            String message = String.format(
                    "写出文件 : [%s] 时出错,请确认文件:[%s]存在且配置的用户有权限写, errorMessage:%s",
                    filePath, filePath, e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.OPEN_FILE_ERROR, message);
        }
    }
    
    @Override
    public String getRemoteFileContent(String filePath) {
        try {
            this.completePendingCommand();
            this.printWorkingDirectory();
            String parentDir = filePath.substring(0,
                    StringUtils.lastIndexOf(filePath, IOUtils.DIR_SEPARATOR));
            this.ftpClient.changeWorkingDirectory(parentDir);
            this.printWorkingDirectory();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream(22);
            this.ftpClient.retrieveFile(filePath, outputStream);
            String result = outputStream.toString();
            IOUtils.closeQuietly(outputStream);
            return result;
        } catch (IOException e) {
            String message = String.format(
                    "读取文件 : [%s] 时出错,请确认文件:[%s]存在且配置的用户有权限读取, errorMessage:%s",
                    filePath, filePath, e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.OPEN_FILE_ERROR, message);
        }
    }
    
    @Override
    public Set<String> getAllFilesInDir(String dir, String prefixFileName) {
        Set<String> allFilesWithPointedPrefix = new HashSet<String>();
        try {
            boolean isDirExist = this.ftpClient.changeWorkingDirectory(dir);
            if (!isDirExist) {
                throw DataXException.asDataXException(
                        FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION,
                        String.format("进入目录[%s]失败", dir));
            }
            this.printWorkingDirectory();
            FTPFile[] fs = this.ftpClient.listFiles(dir);
            // LOG.debug(JSON.toJSONString(this.ftpClient.listNames(dir)));
            LOG.debug(String.format("ls: %s",
                    JSON.toJSONString(fs, SerializerFeature.UseSingleQuotes)));
            for (FTPFile ff : fs) {
                String strName = ff.getName();
                if (strName.startsWith(prefixFileName)) {
                    allFilesWithPointedPrefix.add(strName);
                }
            }
        } catch (IOException e) {
            String message = String
                    .format("获取path:[%s] 下文件列表时发生I/O异常,请确认与ftp服务器的连接正常,拥有目录ls权限, errorMessage:%s",
                            dir, e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION, message, e);
        }
        return allFilesWithPointedPrefix;
    }
    
    @Override
    public void deleteFiles(Set<String> filesToDelete) {
        String eachFile = null;
        boolean deleteOk = false;
        try {
            this.printWorkingDirectory();
            for (String each : filesToDelete) {
                LOG.info(String.format("delete file [%s].", each));
                eachFile = each;
                deleteOk = this.ftpClient.deleteFile(each);
                if (!deleteOk) {
                    String message = String.format(
                            "删除文件:[%s] 时失败,请确认指定文件有删除权限", eachFile);
                    throw DataXException.asDataXException(
                            FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION,
                            message);
                }
            }
        } catch (IOException e) {
            String message = String.format(
                    "删除文件:[%s] 时发生异常,请确认指定文件有删除权限,以及网络交互正常, errorMessage:%s",
                    eachFile, e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION, message, e);
        }
    }
    
    private void printWorkingDirectory() {
        try {
            LOG.info(String.format("current working directory:%s",
                    this.ftpClient.printWorkingDirectory()));
        } catch (Exception e) {
            LOG.warn(String.format("printWorkingDirectory error:%s",
                    e.getMessage()));
        }
    }
    
    @Override
    public void completePendingCommand() {
        /*
         * Q:After I perform a file transfer to the server,
         * printWorkingDirectory() returns null. A:You need to call
         * completePendingCommand() after transferring the file. wiki:
         * http://wiki.apache.org/commons/Net/FrequentlyAskedQuestions
         */
        try {
            boolean isOk = this.ftpClient.completePendingCommand();
            if (!isOk) {
                throw DataXException.asDataXException(
                        FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION,
                        "完成ftp completePendingCommand操作发生异常");
            }
        } catch (IOException e) {
            String message = String.format(
                    "完成ftp completePendingCommand操作发生异常, errorMessage:%s",
                    e.getMessage());
            LOG.error(message);
            throw DataXException.asDataXException(
                    FtpWriterErrorCode.COMMAND_FTP_IO_EXCEPTION, message, e);
        }
    }
    
    /**
     * 向ftp目录中写入文件
     * @param sourceFilePath
     * @param targetFilePath
     */
    @Override
    public void localWriteToFtp(String sourceFilePath,String targetFilePath){
        try(BufferedOutputStream bos = new BufferedOutputStream(this.getOutputStream(targetFilePath));
        ) {
            Files.copy(Paths.get(sourceFilePath),bos);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    }
    
    展开全文
  • ftp工具是一种文件传输下载方式,它是TCP/IP协议栈的一部分;其中FTP又由两部分组成,一部分是FTP的服务器,另一部分是FTP的客户端!它能够高效安全地进行文件传输下载操作!可以使用服务器管理工具来作为FTP的...

    ftp工具是一种文件传输下载方式,它是TCP/IP协议栈的一部分;其中FTP又由两部分组成,一部分是FTP的服务器,另一部分是FTP的客户端!它能够高效安全地进行文件传输下载操作!可以使用服务器管理工具来作为FTP的客户端,进行FTP的操作,实现FTP的下载安装。所以ftp工具的选择也是很重要的。接下来,小编给大家推荐三款简易ftp工具。

    第一款:IIS7服务器管理工具

    它可以批量管理ftp站点,不过这都是基本功能,它最重要的是能定时上传下载、定时备份还能够自动更新。这些功能就是我推荐最主要的原因。可能说没有那么清楚的表达出来它的便捷,但只要你用了,那就一定无法逃脱它的魔掌。

    这款工具的颜色搭配的也挺好看的,绿白相间。界面清晰明了。IIS7服务器批量管理工具好处:批量管理、同步操作、到期提醒、数据安全和定期执行。适用系统:Windows和liunx操作系统。支持Vnc和Ftp批量操作。相信我准没错,这绝对是一款让你爱不释手的免费ftp工具。

    下载地址:IIS7服务器管理工具

    b6513f8a0dc949e8952d6fd42555b415.png

    740a5893bbab949d031c2e2c91a2a90b.png

    第二款:WinSCP

    WinSCP是一个Windows环境下使用SSH的开源图形化SFTP客户端。同时支持SCP协议。它的主要功能就是在本地与远程计算机间安全的复制文件。.winscp也可以链接其他系统,比如linux系统。WinSCP是一款Windows环境下使用的基于SSH的开源文件上传客户端,同时支持SFTP、SCP、FTP协议,你可非常方便地使用拖拽操作,同时也支持批处理脚本及命令行方式操作,WinSCP还内置了文本编辑器,方便你进行文本编辑,对于那些熟悉NC的人来讲用这种操作界面w会更为快速,抛开鼠标操作用传统键盘操作同样可以键指如飞。

    c30e4c159fd821fc594c3f565a38e41c.png

    第三款: FireFTP

    这是一个火狐的插件,必须在火狐Mozilla Firefox浏览器上面才能使用。FireFTP是出品 LiteServe/LiteWeb/LiteFTP 等工具的公司新出的又一个简单小巧且容易上手的 FTP 客户端工具,支持多线程文件传输。

    对FireFTP的工具是一个非常容易使用和更舒适的比很多其他FTP客户端你会发现周围。 Firefox转换成一个更全功能的FTP客户端。 您将欣赏消防的FTP一旦你习惯了。 这是非常有益的。同步:导航时保持目录同步;它是免费的!跨平台:适用于Windows,Mac OS X,Linux;国际:有20多种语言版本;安全:SSL / TLS / SFTP支持,与网上银行和购物相同的加密。

    837f2ed6cd400e274a66370bd93d6231.png
    展开全文
  • ftp工具,FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP...

    ftp工具,FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协议访问位于FTP服务器上的资源。那ftp工具如何连接服务器呢?接下来小编教你使用ftp工具进行远程连接。

    使用工具:IIS7服务器管理工具

    IIS7服务器管理工具里面的ftp服务器不仅具有批量管理的功能,还具有定时上传下载、定时备份和多任务同时进行,最关键的是还能自动更新。我相信自动更新这个功能应该会让很多人都心动吧。说实话,这个功能也是非常吸引小编的。

    不过IIS7服务器管理工具可不止这一个功能。它具备所有服务器管理工具的功能,比如批量管理。同时它还有很多的自主研发功能。比如同步操作、到期提醒、数据安全和定期执行。当然适用的系统也有Windows和liunx操作系统。还支持Vnc和Ftp批量操作。这些都是它的优点,也是我选择它的原因。

    下载地址:IIS7服务器管理工具

    c76ae099df3be197e4f82b80994a3b3d.png

    cf9e6f33bb606ec72c6d0d5c7193be9d.png

    配置ftp工具代码:

    一、安装客户端

    [root@xl ~]# yum install ftp

    二、创建用户

    #以root用户登录后,增加名为 xlftp 的用户,并指定 xlftp 用户的主目录为 /home/xlftp

    [root@xl ~]# useradd -d /home/xlftp xlftp

    #为 xlftp 设置或修改密码

    [root@xl ~]# passwd xlftp

    三、用户登录

    #直接通过ftp命令登录[root@xl ~]# ftp 192.168.1.100

    #在ftp命令模式下登录ftp> open 192.168.1.100

    #指定ftp服务端口登录[root@xl ~]# ftp 192.168.1.100 ​

    展开全文
  • ftp工具的汉化版不是很多,网络上的基本上都是英文的。所以可能会比较的难找一点。ftp工具专业版汉化版的比较符合国人的使用要求,简单方便快捷明了,下面小编给大家介绍三款ftp工具专业版汉化版。第一款:IIS7...

    ftp工具的汉化版不是很多,网络上的基本上都是英文的。所以可能会比较的难找一点。ftp工具专业版汉化版的比较符合国人的使用要求,简单方便快捷明了,下面小编给大家介绍三款ftp工具专业版汉化版。


    第一款:IIS7服务器管理工具

    IIS7服务器管理工具,是一款绿色小巧,功能实用的FTP工具软件,其界面简洁,操作方便,它支持FTP批量上传下载,ftp多站点管理,还拥有定时上传下载的强大功能(定时备份,自动更新等),十分好用。它可以同时连接多台ftp服务器进行文件传输工作,还可以在线解压缩文件,支持文件查找,在线编辑等功能。
    同时它还能够同时远程操作多台服务器,并且多台服务器间可以自由切换,适合机房管理、站长、运维工作、程序员使用。适用于Windows系统,Linux系统和VPS服务器等。

    下载地址:IIS7服务器管理工具

    33ff3eb4378bc364a2ca185ffe92832d.png

    71e9797c8151bfea62e9331ed2ae7412.png

    第二款:FileZilla

    这是一个完全免费、开源、跨平台的FTP客户端软件,虽然免费,但功能却非常强大,支持FTP,FTPS,SFTP等多种文件传输协议,可以进行远程文件搜索和编辑,除此之外,还支持断点续传和SSL加密连接,书签功能和多标签用户界面也非常不错,总的来说,是一款非常优秀的FTP客户端软件:

    51cb0724ec29af0d9711b39027954a9c.png

    第三款:WinSCP

    这是Windows环境下一个使用SSH的开源图形化SFTP客户端软件,同时支持SCP协议,主要用于本机和远程主机间安全的文件复制,可以很方便的进行文件的上传和下载,除此之外,也支持同步浏览和远程文件编辑的功能,对于日常连接FTP来说,是一个非常不错的软件:

    497093182f85fdf634f9e85a4e0575f3.png

    目前,就分享这3个不错的ftp工具吧,对于日常使用FTP来说,完全够用了,当然,还有许多其他FTP客户端软件,像XFTP等也都非常不错,选择适合自己的一款就行,网上也有相关资料和教程,感兴趣的话,可以搜一下,希望以上分享的内容能对你有所帮助吧,也欢迎大家评论、留言进行补充。

    展开全文
  • 无论你是做网站工作,还是运行一个家庭FTP工具,或者你只是喜欢高速下载,一个稳定且功能齐全的FTP工具都可以节省你大量时间和生命,现在有大量的免费或者收费的FTP工具软件供大家选择,这里总结了五个流行的FTP工具...
  • 可能很多人都不太熟悉什么是ftp工具类,但是这个工具使用的人还是非常多的,比如那些从事网站管理的人员。他们的日常工作中接触的最多的工具可能就是ftp工具类。这款工具一般是英文版的偏多,那有没有我们中国自己的...
  • ftp工具是一种文件传输下载方式,它是TCP/IP协议栈的一部分;其中FTP又由两部分组成,一部分是FTP的服务器,另一部分是FTP的客户端!它能够高效安全地进行文件传输下载操作!可以使用服务器管理工具来作为FTP的...
  • ftp工具哪个好用?或许是大家再三比较的几个问题。下面提供的是常见的ftp工具,每款都是免费的,大家可以放心使用。1、IIS7服务器管理工具IIS7服务器管理工具可以批量管理、定时上传下载、同步操作、数据备份、到期...
  • ftp工具专业版的汉化版不是很多,网络上的基本上都是英文的。所以可能会比较的难找一点。ftp工具专业版汉化版的比较符合国人的使用要求,简单方便快捷明了。那ftp工具专业版怎么配置连接呢?下面小编给大家介绍ftp...
  • ftp工具源码

    2018-03-25 02:07:43
    用于管理网站的ftp工具 用于管理网站的ftp工具 用于管理网站的ftp工具
  • ftp工具简介iis7远程桌面管理软件,是一款绿色小巧,功能实用的ftp软件,其界面简洁,操作方便,它支持FTP批量上传下载,它可以同时连接多台ftp服务器进行文件传输工作,还可以在线解压缩文件,支持文件查找,在线...
  • 最小的ftp工具

    2018-07-25 18:46:21
    最小的ftp工具最小的ftp工具最小的ftp工具最小的ftp工具最小的ftp工具
  • 什么是FTP工具FTP工具用来上传建站程序到网站空间的工具。FTP工具是每位站长必不可少的软件,无论做网站还是一般的FTP服务器,一个稳定功能强大的FTP工具都能帮助你节省很多时间和精力。接下来我为大家推荐几款...
  • 一提到ftp工具,大家第一个想到的不知道是什么,有可能你不太熟悉,但从事网站管理人员一定都用过。ftp工具是网络上用来传送文件的工具。ftp工具以汉化版和破解版的居多。但是破解版的一般都比较危险,不建议你们...
  • FTP工具简介FTP工具是基于文件传输协议提供互联网双向传输服务的工具。常用于局域网上传文件下载文件,FTP可以管理多个ftp站点,使用拖拉即可完成文件或文件夹的上传、下载查看、编辑、删除,移动文件等操作。windows ...
  • 非常好用的ftp工具,非常好用的ftp工具,非常好用的ftp工具,非常好用的ftp工具,非常好用的ftp工具
  • 下面我们就与FTP工具来举例说面一下,FTP工具就是基于文件传输协议提供互联网双向传输服务的工具。FTP工具常用于局域网上传文件下载文件,比如校园网下载资源,或者框架建设资源站等。 第一款:IIS7服务器管理工具...
  • FTP工具,5款常用的FTP工具 FTP工具是每个网站管理人员必须要配备的实用工具,那么大家最常用的5款FTP工具是什么呢?下面就让小编为您介绍一下吧! 一、iis7服务器管理工具 iis7服务器管理工具是小编强烈推荐的一款...
  • 常用的ftp服务器有server-U、FileZilla、iis7服务器管理工具ftp客户端工具等,其中iis7服务器管理...iis7远程桌面管理软件,是一款绿色小巧,功能实用的FTP工具软件,其界面简洁,操作方便,它支持FTP批量上传下载,...
  • 很多使用ftp工具的人肯定都会有这种疑问,毕竟上传下载文件太慢了真的很不方便,所以需要比较快一点的ftp工具,小编用过几款稍微快一点的ftp工具。接下来推荐三款好用又比较快的ftp工具吧。第一款:IIS7服务器管理...
  • ftp工具,FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP...
  • 对于ftp工具,你了解多少?其实一般人也接触不到这种软件ftp工具主要是针对从事网站管理的工作人员比较有利的一款工具。可以帮助他们快速的解决工作中的问题。方便、简单、快捷又明了的解决问题,那电脑常用的ftp...
  • FTP工具简介FTP工具是基于文件传输协议提供互联网双向传输服务的工具。常用于局域网上传文件下载文件,FTP可以管理多个ftp站点,使用拖拉即可完成文件或文件夹的上传、下载查看、编辑、删除,移动文件等操作。windows ...
  • 美能达C266FTP扫描设置+FTP工具
  • 市面上有很多ftp服务器软件,但是功能参差不齐,安全性太多没有保障,小编也进了很多坑,为了让您少走弯路,今天给大家分享8款常见的ftp工具。每款都很有特色,感兴趣的小伙伴可以去下载试试。1、IIS7服务器管理工具...
  • ftp指用于Internet上的控制文件双向传输(下载和上传),可以自由存取和管理FTP服务器的资源,通过拖放即可完成文件或文件夹上传,使用方便且高效。 IIS7服务器管理工具可以批量管理、...3.然后就能看到ftp工具的使用
  • 网络上有很多ftp工具,那选择哪一款才不入坑呢,小编刚接触到ftp也是被坑了很多次,为避免你们和小编一样,小编决定和您们分享一款超级好用的ftp工具。 IIS7服务管理工具最好的ftp工具。IIS7服务管理工具,是一款...
  • 网络上最不好找的就是绿色版的工具,毕竟在现在这个年代不可能让你免费使用别人的产品,所以绿色版的工具是真的难找。相信常常使用电脑的小伙伴...它不仅拥有每个java ftp工具类都具备的批量管理功能,还具备很多你意想

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,326
精华内容 6,930
关键字:

ftp工具