-
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的实现。如下:
代码结构:
- IFtpHelper(ftp接口)
- SftpHelperImpl(sftp实现)
- 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 工具_ftp工具,简易ftp工具
2020-11-29 22:50:22ftp工具是一种文件传输下载方式,它是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服务器管理工具
第二款:WinSCP
WinSCP是一个Windows环境下使用SSH的开源图形化SFTP客户端。同时支持SCP协议。它的主要功能就是在本地与远程计算机间安全的复制文件。.winscp也可以链接其他系统,比如linux系统。WinSCP是一款Windows环境下使用的基于SSH的开源文件上传客户端,同时支持SFTP、SCP、FTP协议,你可非常方便地使用拖拽操作,同时也支持批处理脚本及命令行方式操作,WinSCP还内置了文本编辑器,方便你进行文本编辑,对于那些熟悉NC的人来讲用这种操作界面w会更为快速,抛开鼠标操作用传统键盘操作同样可以键指如飞。
第三款: FireFTP
这是一个火狐的插件,必须在火狐Mozilla Firefox浏览器上面才能使用。FireFTP是出品 LiteServe/LiteWeb/LiteFTP 等工具的公司新出的又一个简单小巧且容易上手的 FTP 客户端工具,支持多线程文件传输。
对FireFTP的工具是一个非常容易使用和更舒适的比很多其他FTP客户端你会发现周围。 Firefox转换成一个更全功能的FTP客户端。 您将欣赏消防的FTP一旦你习惯了。 这是非常有益的。同步:导航时保持目录同步;它是免费的!跨平台:适用于Windows,Mac OS X,Linux;国际:有20多种语言版本;安全:SSL / TLS / SFTP支持,与网上银行和购物相同的加密。
-
ftp 工具_ftp工具,ftp工具如何连接服务器
2020-11-29 22:53:03ftp工具,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服务器管理工具
配置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工具专业版汉化版
2020-11-08 02:07:48ftp工具的汉化版不是很多,网络上的基本上都是英文的。所以可能会比较的难找一点。ftp工具专业版汉化版的比较符合国人的使用要求,简单方便快捷明了,下面小编给大家介绍三款ftp工具专业版汉化版。第一款:IIS7...ftp工具的汉化版不是很多,网络上的基本上都是英文的。所以可能会比较的难找一点。ftp工具专业版汉化版的比较符合国人的使用要求,简单方便快捷明了,下面小编给大家介绍三款ftp工具专业版汉化版。
第一款:IIS7服务器管理工具IIS7服务器管理工具,是一款绿色小巧,功能实用的FTP工具软件,其界面简洁,操作方便,它支持FTP批量上传下载,ftp多站点管理,还拥有定时上传下载的强大功能(定时备份,自动更新等),十分好用。它可以同时连接多台ftp服务器进行文件传输工作,还可以在线解压缩文件,支持文件查找,在线编辑等功能。
同时它还能够同时远程操作多台服务器,并且多台服务器间可以自由切换,适合机房管理、站长、运维工作、程序员使用。适用于Windows系统,Linux系统和VPS服务器等。下载地址:IIS7服务器管理工具
第二款:FileZilla
这是一个完全免费、开源、跨平台的FTP客户端软件,虽然免费,但功能却非常强大,支持FTP,FTPS,SFTP等多种文件传输协议,可以进行远程文件搜索和编辑,除此之外,还支持断点续传和SSL加密连接,书签功能和多标签用户界面也非常不错,总的来说,是一款非常优秀的FTP客户端软件:
第三款:WinSCP
这是Windows环境下一个使用SSH的开源图形化SFTP客户端软件,同时支持SCP协议,主要用于本机和远程主机间安全的文件复制,可以很方便的进行文件的上传和下载,除此之外,也支持同步浏览和远程文件编辑的功能,对于日常连接FTP来说,是一个非常不错的软件:
目前,就分享这3个不错的ftp工具吧,对于日常使用FTP来说,完全够用了,当然,还有许多其他FTP客户端软件,像XFTP等也都非常不错,选择适合自己的一款就行,网上也有相关资料和教程,感兴趣的话,可以搜一下,希望以上分享的内容能对你有所帮助吧,也欢迎大家评论、留言进行补充。
-
ftp 工具_ftp,ftp工具下载
2020-11-28 20:58:16无论你是做网站工作,还是运行一个家庭FTP工具,或者你只是喜欢高速下载,一个稳定且功能齐全的FTP工具都可以节省你大量时间和生命,现在有大量的免费或者收费的FTP工具软件供大家选择,这里总结了五个流行的FTP工具... -
和ftp_ftp工具,ftp工具类
2021-01-05 01:58:54可能很多人都不太熟悉什么是ftp工具类,但是这个工具使用的人还是非常多的,比如那些从事网站管理的人员。他们的日常工作中接触的最多的工具可能就是ftp工具类。这款工具一般是英文版的偏多,那有没有我们中国自己的... -
链接ftp命令行_ftp工具,简易ftp工具
2021-01-13 21:08:33ftp工具是一种文件传输下载方式,它是TCP/IP协议栈的一部分;其中FTP又由两部分组成,一部分是FTP的服务器,另一部分是FTP的客户端!它能够高效安全地进行文件传输下载操作!可以使用服务器管理工具来作为FTP的... -
ftp 工具_ftp,常见的ftp工具
2020-11-30 13:29:54ftp工具哪个好用?或许是大家再三比较的几个问题。下面提供的是常见的ftp工具,每款都是免费的,大家可以放心使用。1、IIS7服务器管理工具IIS7服务器管理工具可以批量管理、定时上传下载、同步操作、数据备份、到期... -
ftp工具,ftp工具专业版
2020-08-21 13:14:41ftp工具专业版的汉化版不是很多,网络上的基本上都是英文的。所以可能会比较的难找一点。ftp工具专业版汉化版的比较符合国人的使用要求,简单方便快捷明了。那ftp工具专业版怎么配置连接呢?下面小编给大家介绍ftp... -
ftp工具源码
2018-03-25 02:07:43用于管理网站的ftp工具 用于管理网站的ftp工具 用于管理网站的ftp工具 -
ftp 工具_ftp工具,ftp工具如何下载使用?Linux如何配置ftp服务器?
2020-11-28 20:58:15ftp工具简介iis7远程桌面管理软件,是一款绿色小巧,功能实用的ftp软件,其界面简洁,操作方便,它支持FTP批量上传下载,它可以同时连接多台ftp服务器进行文件传输工作,还可以在线解压缩文件,支持文件查找,在线... -
最小的ftp工具
2018-07-25 18:46:21最小的ftp工具最小的ftp工具最小的ftp工具最小的ftp工具最小的ftp工具 -
FTP工具,3款FTP工具推荐
2020-07-02 16:02:23什么是FTP工具?FTP工具用来上传建站程序到网站空间的工具。FTP工具是每位站长必不可少的软件,无论做网站还是一般的FTP服务器,一个稳定功能强大的FTP工具都能帮助你节省很多时间和精力。接下来我为大家推荐几款... -
ftp工具,ftp工具的使用方法
2020-08-19 16:03:14一提到ftp工具,大家第一个想到的不知道是什么,有可能你不太熟悉,但从事网站管理人员一定都用过。ftp工具是网络上用来传送文件的工具。ftp工具以汉化版和破解版的居多。但是破解版的一般都比较危险,不建议你们... -
ftp 上传文件夹_ftp工具,windows ftp工具,windows如何安装FTP?
2020-11-29 22:52:02FTP工具简介FTP工具是基于文件传输协议提供互联网双向传输服务的工具。常用于局域网上传文件下载文件,FTP可以管理多个ftp站点,使用拖拉即可完成文件或文件夹的上传、下载查看、编辑、删除,移动文件等操作。windows ... -
ftp工具,非常好用的ftp工具
2010-05-25 08:21:42非常好用的ftp工具,非常好用的ftp工具,非常好用的ftp工具,非常好用的ftp工具,非常好用的ftp工具 -
FTP工具,你知道的FTP工具有哪些,5款最好用的FTP工具
2020-07-09 17:07:43下面我们就与FTP工具来举例说面一下,FTP工具就是基于文件传输协议提供互联网双向传输服务的工具。FTP工具常用于局域网上传文件下载文件,比如校园网下载资源,或者框架建设资源站等。 第一款:IIS7服务器管理工具... -
FTP工具,5款常用的FTP工具
2020-06-29 17:13:45FTP工具,5款常用的FTP工具 FTP工具是每个网站管理人员必须要配备的实用工具,那么大家最常用的5款FTP工具是什么呢?下面就让小编为您介绍一下吧! 一、iis7服务器管理工具 iis7服务器管理工具是小编强烈推荐的一款... -
ftp连接工具_ftp工具使用,ftp工具使用方法教程,怎么连接?
2020-11-30 13:44:22常用的ftp服务器有server-U、FileZilla、iis7服务器管理工具ftp客户端工具等,其中iis7服务器管理...iis7远程桌面管理软件,是一款绿色小巧,功能实用的FTP工具软件,其界面简洁,操作方便,它支持FTP批量上传下载,... -
ftp工具哪个好用_比较快的ftp工具,推荐三款好用又比较快的ftp工具
2020-11-30 13:29:53很多使用ftp工具的人肯定都会有这种疑问,毕竟上传下载文件太慢了真的很不方便,所以需要比较快一点的ftp工具,小编用过几款稍微快一点的ftp工具。接下来推荐三款好用又比较快的ftp工具吧。第一款:IIS7服务器管理... -
工具的使用 连接服务_ftp工具,ftp工具如何连接服务器
2021-01-14 04:35:49ftp工具,FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP... -
ftp工具,电脑常用的ftp工具有哪些
2020-08-24 14:43:29对于ftp工具,你了解多少?其实一般人也接触不到这种软件ftp工具主要是针对从事网站管理的工作人员比较有利的一款工具。可以帮助他们快速的解决工作中的问题。方便、简单、快捷又明了的解决问题,那电脑常用的ftp... -
ftp一直弹出用户名密码_ftp工具,windows ftp工具,windows如何安装FTP?
2021-01-20 00:53:59FTP工具简介FTP工具是基于文件传输协议提供互联网双向传输服务的工具。常用于局域网上传文件下载文件,FTP可以管理多个ftp站点,使用拖拉即可完成文件或文件夹的上传、下载查看、编辑、删除,移动文件等操作。windows ... -
美能达C266FTP扫描设置+FTP工具
2018-05-06 11:14:30美能达C266FTP扫描设置+FTP工具 -
ftp 传输速度_ftp工具,常见的ftp工具有哪些
2020-11-08 02:07:32市面上有很多ftp服务器软件,但是功能参差不齐,安全性太多没有保障,小编也进了很多坑,为了让您少走弯路,今天给大家分享8款常见的ftp工具。每款都很有特色,感兴趣的小伙伴可以去下载试试。1、IIS7服务器管理工具... -
ftp工具,ftp工具是干什么的
2020-08-25 13:29:02ftp指用于Internet上的控制文件双向传输(下载和上传),可以自由存取和管理FTP服务器的资源,通过拖放即可完成文件或文件夹上传,使用方便且高效。 IIS7服务器管理工具可以批量管理、...3.然后就能看到ftp工具的使用 -
ftp工具,4步完成ftp工具 知乎的安装
2020-08-25 15:10:29网络上有很多ftp工具,那选择哪一款才不入坑呢,小编刚接触到ftp也是被坑了很多次,为避免你们和小编一样,小编决定和您们分享一款超级好用的ftp工具。 IIS7服务管理工具最好的ftp工具。IIS7服务管理工具,是一款... -
ftp工具 绿色,细数3款绿色 ftp工具
2020-07-20 15:23:57网络上最不好找的就是绿色版的工具,毕竟在现在这个年代不可能让你免费使用别人的产品,所以绿色版的工具是真的难找。相信常常使用电脑的小伙伴...它不仅拥有每个java ftp工具类都具备的批量管理功能,还具备很多你意想