没有写摘要的习惯,就直接在这里写了。

首先搭建一个文件服务器,参考http://my.oschina.net/simpleton/blog/530081

然后就是客户端工具类代码(2015-11-16 11:00:16更新,下午才测试这段代码,暂时贴上来)

这里说明一下,客户端代码是写的一个核心代码,然后根据自己的需要,对其进行不同的包装。

为了让核心代码更高效和更具扩展、易用,核心代码可能会经常重构,到时候我会贴上最新的代码并保留原来的。

/**

*

*/

package com.common.file;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import org.apache.commons.lang.StringUtils;

import org.apache.commons.net.ftp.FTPClient;

import org.apache.commons.net.ftp.FTPReply;

import org.apache.log4j.Logger;

/**

* FTP客户端工具类

* @author luolin

*

* @version $id:FTPClientUtils.java,v 0.1 2015年11月13日 下午4:18:07 luolin Exp $

*/

public class FTPClientUtil {

private static final Logger LOGGER = Logger.getLogger(FTPClientUtil.class);

/**

* 连接文件服务器

* @param addr 文件服务器地址

* @param port 端口

* @param username 用户名

* @param password 密码

* @throws Exception

*/

public static FTPClient connect(String addr, int port, String username, String password) {

LOGGER.info("【连接文件服务器】addr = " + addr + " , port : " + port + " , username = " + username + " , password = "

+ password);

FTPClient ftpClient = new FTPClient();

try {

// 连接

ftpClient.connect(addr, port);

// 登录

ftpClient.login(username, password);

ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

} catch (Exception e) {

LOGGER.error("【连接文件服务器失败】", e);

throw new RuntimeException("连接文件服务器失败");

}

// 判断文件服务器是否可用??

if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {

closeConnection(ftpClient);

}

return ftpClient;

}

/**

* 连接文件服务器

* @param addr 文件服务器地址

* @param port 端口

* @param username 用户名

* @param password 密码

* @param workingDirectory 目标连接工作目录

* @throws Exception

*/

public static FTPClient connect(String addr, int port, String username, String password, String workingDirectory)

throws Exception {

FTPClient ftpClient = connect(workingDirectory, port, workingDirectory, workingDirectory);

changeWorkingDirectory(workingDirectory, ftpClient);

return ftpClient;

}

/**

* 关闭连接,使用完连接之后,一定要关闭连接,否则服务器会抛出 Connection reset by peer的错误

* @throws IOException

*/

public static void closeConnection(FTPClient ftpClient) {

LOGGER.info("【关闭文件服务器连接】");

if (ftpClient == null) {

return;

}

try {

ftpClient.disconnect();

} catch (IOException e) {

LOGGER.error("【关闭连接失败】", e);

throw new RuntimeException("关闭连接失败");

}

}

/**

* 切换工作目录

* @param directory 目标工作目录

* @param ftpClient

* @throws IOException

*/

public static void changeWorkingDirectory(String directory, FTPClient ftpClient) {

LOGGER.info("【切换工作目录】directory : " + directory);

// 切换到目标工作目录

try {

if (!ftpClient.changeWorkingDirectory(directory)) {

ftpClient.makeDirectory(directory);

ftpClient.changeWorkingDirectory(directory);

}

} catch (IOException e) {

LOGGER.error("【切换工作目录失败】", e);

throw new RuntimeException("切换工作目录失败");

}

}

/**

* 上传文件/文件夹

* @param file 上传的文件或文件夹

* @return 文件存放的路径以及文件名

* @throws Exception

*/

public static void upload(File file, FTPClient ftpClient) throws Exception {

if (file == null) {

LOGGER.warn("【存储的文件为空】");

throw new RuntimeException("上传文件为空");

}

LOGGER.info("【上传文件/文件夹】file : " + file.getName());

// 是文件,直接上传

if (!file.isDirectory()) {

storeFile(new File(file.getPath()), ftpClient);

return;

}

changeWorkingDirectory(file.getName(), ftpClient);

// 文件夹,递归上传所有文件

for (File item : file.listFiles()) {

if (!item.isDirectory()) {

storeFile(item, ftpClient);

continue;

}

upload(item, ftpClient);

ftpClient.changeToParentDirectory();

}

}

/**

* 删除文件

* @param fileName 要删除的文件地址

* @return true/false

* @throws IOException

*/

public static boolean delete(String fileName, FTPClient ftpClient) throws IOException {

LOGGER.info("【删除文件】fileName : " + fileName);

return ftpClient.deleteFile(fileName);

}

/**

* 存储文件

* @param file {@link File}

* @throws Exception

*/

public static void storeFile(File file, FTPClient ftpClient) throws Exception {

if (file == null) {

LOGGER.warn("【存储的文件为空】");

throw new RuntimeException("存储的文件为空");

}

LOGGER.info("【存储文件】file : " + file.getName());

FileInputStream input = new FileInputStream(file);

ftpClient.storeFile(file.getName(), input);

input.close();

}

/**

* 下载文件到指定目录

* @param ftpFile 文件服务器上的文件地址

* @param dstFile 输出文件的路径和名称

* @throws Exception

*/

public static void downLoad(String ftpFile, String dstFile, FTPClient ftpClient) throws Exception {

LOGGER.info("【下载文件到指定目录】ftpFile = " + ftpFile + " , dstFile = " + dstFile);

if (StringUtils.isBlank(ftpFile)) {

LOGGER.warn("【参数ftpFile为空】");

throw new RuntimeException("【参数ftpFile为空】");

}

if (StringUtils.isBlank(dstFile)) {

LOGGER.warn("【参数dstFile为空】");

throw new RuntimeException("【参数dstFile为空】");

}

File file = new File(dstFile);

FileOutputStream fos = new FileOutputStream(file);

ftpClient.retrieveFile(ftpFile, fos);

fos.flush();

fos.close();

}

/**

* 从文件服务器获取文件流

* @param ftpFile 文件服务器上的文件地址

* @return {@link InputStream}

* @throws IOException

*/

public static InputStream retrieveFileStream(String ftpFile, FTPClient ftpClient) throws IOException {

LOGGER.info("【从文件服务器获取文件流】ftpFile : " + ftpFile);

if (StringUtils.isBlank(ftpFile)) {

LOGGER.warn("【参数ftpFile为空】");

throw new RuntimeException("【参数ftpFile为空】");

}

return ftpClient.retrieveFileStream(ftpFile);

}

}

2015-11-24 16:42:22更新:增加了拷贝方法,其他地方也做了一些优化;我还写了一个包装类(FTPManager),将FTPClientUtil进一步封装了一下,以便调用者只需要关心文件操作业务,不再关心连接文件服务器等操作

/**

*

*/

package com.common.file;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import org.apache.commons.lang.NullArgumentException;

import org.apache.commons.lang.StringUtils;

import org.apache.commons.net.ftp.FTPClient;

import org.apache.commons.net.ftp.FTPReply;

import org.apache.log4j.Logger;

import com.common.DateUtils;

/**

* FTP客户端工具类

* @author luolin

*

* @version $id:FTPClientUtils.java,v 0.1 2015年11月13日 下午4:18:07 luolin Exp $

*/

public class FTPClientUtil {

private static final Logger LOGGER = Logger.getLogger(FTPClientUtil.class);

/**

* 连接文件服务器

* @param addr 文件服务器地址

* @param port 端口

* @param username 用户名

* @param password 密码

* @throws Exception

*/

public static FTPClient connect(String addr, int port, String username, String password) {

LOGGER.info("【连接文件服务器】addr = " + addr + " , port : " + port + " , username = " + username + " , password = "

+ password);

FTPClient ftpClient = new FTPClient();

try {

// 连接

ftpClient.connect(addr, port);

// 登录

ftpClient.login(username, password);

// 被动模式:每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据(参考资料:FTP主动/被动模式的解释)

ftpClient.enterLocalPassiveMode();

ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

} catch (Exception e) {

LOGGER.error("【连接文件服务器失败】", e);

throw new RuntimeException("连接文件服务器失败");

}

// 判断文件服务器是否可用??

if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {

closeConnection(ftpClient);

}

return ftpClient;

}

/**

* 连接文件服务器

* @param addr 文件服务器地址

* @param port 端口

* @param username 用户名

* @param password 密码

* @param workingDirectory 目标连接工作目录

* @throws Exception

*/

public static FTPClient connect(String addr, int port, String username, String password, String workingDirectory)

throws Exception {

FTPClient ftpClient = connect(addr, port, username, password);

changeWorkingDirectory(workingDirectory, ftpClient);

return ftpClient;

}

/**

* 关闭连接,使用完连接之后,一定要关闭连接,否则服务器会抛出 Connection reset by peer的错误

* @throws IOException

*/

public static void closeConnection(FTPClient ftpClient) {

LOGGER.info("【关闭文件服务器连接】");

if (ftpClient == null) {

return;

}

try {

ftpClient.disconnect();

} catch (IOException e) {

LOGGER.error("【关闭连接失败】", e);

throw new RuntimeException("关闭连接失败");

}

}

/**

* 切换工作目录

* @param directory 目标工作目录

* @param ftpClient

* @throws IOException

*/

public static void changeWorkingDirectory(String directory, FTPClient ftpClient) {

LOGGER.info("【切换工作目录】directory : " + directory);

baseValidate(ftpClient);

// 切换到目标工作目录

try {

if (!ftpClient.changeWorkingDirectory(directory)) {

ftpClient.makeDirectory(directory);

ftpClient.changeWorkingDirectory(directory);

}

} catch (Throwable e) {

LOGGER.error("【切换工作目录失败】", e);

throw new RuntimeException("切换工作目录失败");

}

}

/**

* 上传文件/文件夹

* @param file 上传的文件或文件夹

* @return 文件存放的路径以及文件名

* @throws Exception

*/

public static void upload(File file, FTPClient ftpClient) throws Exception {

if (file == null) {

LOGGER.warn("【存储的文件为空】");

throw new RuntimeException("上传文件为空");

}

LOGGER.info("【上传文件/文件夹】file : " + file.getName());

baseValidate(ftpClient);

// 是文件,直接上传

if (!file.isDirectory()) {

storeFile(new File(file.getPath()), ftpClient);

return;

}

changeWorkingDirectory(file.getName(), ftpClient);

// 文件夹,递归上传所有文件

for (File item : file.listFiles()) {

if (!item.isDirectory()) {

storeFile(item, ftpClient);

continue;

}

upload(item, ftpClient);

ftpClient.changeToParentDirectory();

}

}

/**

* 删除文件

* @param fileName 要删除的文件地址

* @return true/false

* @throws IOException

*/

public static boolean delete(String fileName, FTPClient ftpClient) throws IOException {

LOGGER.info("【删除文件】fileName : " + fileName);

baseValidate(ftpClient);

if (StringUtils.isBlank(fileName)) {

LOGGER.warn("【参数fileName为空】");

throw new NullArgumentException("fileName");

}

return ftpClient.deleteFile(fileName);

}

/**

* 存储文件

* @param file {@link File}

* @throws Exception

*/

public static void storeFile(File file, FTPClient ftpClient) throws Exception {

if (file == null) {

LOGGER.warn("【存储的文件为空】");

throw new RuntimeException("存储的文件为空");

}

LOGGER.info("【存储文件】file : " + file.getName());

baseValidate(ftpClient);

FileInputStream input = new FileInputStream(file);

ftpClient.storeFile(file.getName(), input);

input.close();

}

/**

* 存储文件

* @param inputStream {@link InputStream}

* @param fileName 文件名

* @throws Exception

*/

public static void storeFile(InputStream inputStream, String fileName, FTPClient ftpClient) throws Exception {

LOGGER.info("【存储文件】fileName = " + fileName);

if (inputStream == null) {

LOGGER.warn("【参数inputStream为空】");

throw new RuntimeException("存储的文件为空");

}

baseValidate(ftpClient);

ftpClient.storeFile(fileName, inputStream);

inputStream.close();

}

/**

* 下载文件到指定目录

* @param ftpFile 文件服务器上的文件地址

* @param dstFile 输出文件的路径和名称

* @throws Exception

*/

public static void downLoad(String ftpFile, String dstFile, FTPClient ftpClient) throws Exception {

LOGGER.info("【下载文件到指定目录】ftpFile = " + ftpFile + " , dstFile = " + dstFile);

if (StringUtils.isBlank(ftpFile)) {

LOGGER.warn("【参数ftpFile为空】");

throw new RuntimeException("【参数ftpFile为空】");

}

if (StringUtils.isBlank(dstFile)) {

LOGGER.warn("【参数dstFile为空】");

throw new RuntimeException("【参数dstFile为空】");

}

baseValidate(ftpClient);

File file = new File(dstFile);

FileOutputStream fos = new FileOutputStream(file);

ftpClient.retrieveFile(ftpFile, fos);

fos.flush();

fos.close();

}

/**

* 从文件服务器获取文件流

* @param ftpFile 文件服务器上的文件地址

* @return {@link InputStream}

* @throws IOException

*/

public static InputStream retrieveFileStream(String ftpFile, FTPClient ftpClient) throws IOException {

LOGGER.info("【从文件服务器获取文件流】ftpFile : " + ftpFile);

if (StringUtils.isBlank(ftpFile)) {

LOGGER.warn("【参数ftpFile为空】");

throw new RuntimeException("【参数ftpFile为空】");

}

baseValidate(ftpClient);

return ftpClient.retrieveFileStream(ftpFile);

}

/**

* 复制文件

* @param ftpClient {@link FTPClient}

* @param sourceFile 源文件

* @param targetDir 目标文件夹

* @return 复制后的文件路径及文件名

* @throws Exception

*/

public static String copy(FTPClient ftpClient, String sourceFile, String targetDir) throws Exception {

return copy(ftpClient, sourceFile, targetDir, FileUtil.getFileNameNoPath(sourceFile));

}

/**

* 复制文件

* @param ftpClient {@link FTPClient}

* @param sourceFile 源文件

* @param targetDir 目标文件夹

* @param newName 新的文件名

* @return 复制后的文件路径及文件名

* @throws Exception

*/

public static String copy(FTPClient ftpClient, String sourceFile, String targetDir, String newName)

throws Exception {

LOGGER.info("【拷贝文件】sourceFile = " + sourceFile + " , targetDir = " + targetDir + " , newName = " + newName);

if (StringUtils.isBlank(sourceFile)) {

LOGGER.warn("【参数sourceFile为空】");

throw new NullArgumentException("sourceFile");

}

if (StringUtils.isBlank(targetDir)) {

LOGGER.warn("【参数targetDir为空】");

throw new NullArgumentException("targetDir");

}

if (StringUtils.isBlank(newName)) {

LOGGER.warn("【参数newName为空】");

throw new NullArgumentException("newName");

}

baseValidate(ftpClient);

LOGGER.info("【从文件服务器读取源文件到输入流中】");

InputStream is = ftpClient.retrieveFileStream(sourceFile);

// 主动调用一次getReply()把接下来的226消费掉. 这样做是可以解决这个返回null问题

ftpClient.getReply();

if (is == null) {

LOGGER.warn("【未找到源文件】");

throw new RuntimeException("未找到源文件");

}

LOGGER.info("【将输入流存储到指定的目录】");

changeWorkingDirectory(targetDir, ftpClient);

changeWorkingDirectory(DateUtils.getNow(DateUtils.FORMAT_SHORT_FOLDER), ftpClient);

storeFile(is, newName, ftpClient);

return ftpClient.printWorkingDirectory() + File.separator + newName;

}

/**

* 基本校验

* @param ftpClient {@link FTPClient}

*/

private static void baseValidate(FTPClient ftpClient) {

if (ftpClient == null) {

LOGGER.warn("【参数ftpClient为空】");

throw new NullArgumentException("ftpClient");

}

}

}

FTPManager.java代码:

/**

*

*/

package com.common.file;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import javax.annotation.Resource;

import org.apache.commons.lang.NullArgumentException;

import org.apache.commons.lang.StringUtils;

import org.apache.commons.net.ftp.FTPClient;

import org.apache.log4j.Logger;

import org.springframework.stereotype.Component;

import com.common.DateUtils;

import com.common.property.FileSystemProperties;

/**

* FTP文件管理器

* @author luolin

*

* @version $id:FTPManager.java,v 0.1 2015年11月16日 上午11:08:13 luolin Exp $

*/

@Component("ftpManager")

public class FTPManager {

private static final Logger LOGGER = Logger.getLogger(FTPManager.class);

/** file.system.properties文件内容映射类 */

@Resource(name = "fileSystemProperties")

private FileSystemProperties fileSystemProperties;

/**

* 上传文件到FTP服务器

* @param file {@link File}

* @return 文件上传到服务器的地址

*/

public String upload(File file) {

LOGGER.info("【上传文件到FTP服务器】");

if (file == null) {

LOGGER.warn("【参数file为空】");

throw new NullArgumentException("file");

}

FTPClient ftpClient = connectServer(fileSystemProperties.getProjectWorkingDirectory());

// 切换到子目录,按日期,每天创建一个目录

String subFolder = DateUtils.getNow(DateUtils.FORMAT_SHORT_FOLDER);

FTPClientUtil.changeWorkingDirectory(subFolder, ftpClient);

try {

FTPClientUtil.upload(file, ftpClient);

} catch (Exception e) {

LOGGER.error("【文件上传失败】", e);

throw new RuntimeException("文件上传失败");

} finally {

FTPClientUtil.closeConnection(ftpClient);

}

String uploadedFilePath = fileSystemProperties.getProjectWorkingDirectory() + File.separator + subFolder

+ File.separator + file.getName();

LOGGER.info("【文件上传完成】uploadedFilePath = " + uploadedFilePath);

return uploadedFilePath;

}

/**

* 上传文件到FTP服务器

* @param file {@link File}

* @param targetFolder 目标子目录

* @return 文件上传到服务器的地址

*/

public String upload(File file, String targetFolder) {

LOGGER.info("【上传文件到FTP服务器】targetFolder : " + targetFolder);

if (file == null) {

LOGGER.warn("【参数file为空】");

throw new NullArgumentException("file");

}

FTPClient ftpClient = connectServer(fileSystemProperties.getProjectWorkingDirectory());

// 切换到子目录,按日期,每天创建一个目录

String subFolder = DateUtils.getNow(DateUtils.FORMAT_SHORT_FOLDER);

FTPClientUtil.changeWorkingDirectory(targetFolder, ftpClient);

FTPClientUtil.changeWorkingDirectory(subFolder, ftpClient);

try {

FTPClientUtil.upload(file, ftpClient);

} catch (Exception e) {

LOGGER.error("【文件上传失败】", e);

throw new RuntimeException("文件上传失败");

} finally {

FTPClientUtil.closeConnection(ftpClient);

}

String uploadedFilePath = fileSystemProperties.getProjectWorkingDirectory() + File.separator + targetFolder

+ File.separator + subFolder + File.separator + file.getName();

LOGGER.info("【文件上传完成】uploadedFilePath = " + uploadedFilePath);

return uploadedFilePath;

}

/**

* 连接服务器

* @return {@link FTPClient}

*/

private FTPClient connectServer(String workingDirectory) {

FTPClient ftpClient = null;

try {

// 连接服务器,并切换到对应的项目文件存储目录

ftpClient = FTPClientUtil.connect(fileSystemProperties.getHost(), fileSystemProperties.getPort(),

fileSystemProperties.getUsername(), fileSystemProperties.getPwd(), workingDirectory);

} catch (Exception e) {

LOGGER.error("【连接服务器失败】", e);

throw new RuntimeException("连接服务器失败");

}

return ftpClient;

}

/**

* 连接服务器

* @return {@link FTPClient}

*/

private FTPClient connectServer() {

FTPClient ftpClient = null;

try {

// 连接服务器,并切换到对应的项目文件存储目录

ftpClient = FTPClientUtil.connect(fileSystemProperties.getHost(), fileSystemProperties.getPort(),

fileSystemProperties.getUsername(), fileSystemProperties.getPwd());

} catch (Exception e) {

LOGGER.error("【连接服务器失败】", e);

throw new RuntimeException("连接服务器失败");

}

return ftpClient;

}

/**

* 从服务器获取文件输入流

* @param fileName 文件路径和名称

* @return {@link InputStream}

*/

public InputStream getFileInputStream(String fileName) {

LOGGER.info("【从服务器获取文件输入流】fileName = " + fileName);

if (StringUtils.isBlank(fileName)) {

LOGGER.warn("【参数fileName为空】");

throw new NullArgumentException("fileName");

}

FTPClient ftpClient = connectServer();

try {

return FTPClientUtil.retrieveFileStream(fileName, ftpClient);

} catch (IOException e) {

LOGGER.error("【获取文件流失败】", e);

throw new RuntimeException("获取文件流失败");

} finally {

FTPClientUtil.closeConnection(ftpClient);

}

}

/**

* 从文件服务器文件下载到应用服务器本地

* @param fileName 文件路径及名称

* @param tmpPath 临时文件存放目录

* @return 存储到临时文件目录的完整路径

*/

public String downloadFileToLocal(String fileName, String tmpPath) {

LOGGER.info("【从文件服务器文件下载到应用服务器本地】fileName = " + fileName);

if (StringUtils.isBlank(fileName)) {

LOGGER.warn("【参数fileName为空】");

throw new NullArgumentException("fileName");

}

FTPClient ftpClient = connectServer();

String name = FileUtil.getFileNameNoPath(fileName);

try {

FTPClientUtil.downLoad(fileName, tmpPath + File.separator + name, ftpClient);

} catch (Exception e) {

LOGGER.error("【下载文件失败】", e);

throw new RuntimeException("下载文件失败");

} finally {

FTPClientUtil.closeConnection(ftpClient);

}

return tmpPath + File.separator + name;

}

/**

* 删除文件服务器的文件

* @param fileName 文件在文件服务器的地址

* @throws IOException

*/

public void delete(String fileName) throws IOException {

LOGGER.info("【删除文件服务器的文件】fileName = " + fileName);

FTPClientUtil.delete(fileName, connectServer());

}

/**

* 文件拷贝

* @param sourceFile 源文件地址

* @param targetDir 目标文件夹

* @return 文件拷贝后的完整路径

*/

public String copy(String sourceFile, String targetDir) {

LOGGER.info("【文件拷贝】sourceFile = " + sourceFile + " , targetDir = " + targetDir);

if (StringUtils.isBlank(sourceFile)) {

LOGGER.warn("【参数sourceFile为空】");

throw new NullArgumentException("sourceFile");

}

if (StringUtils.isBlank(targetDir)) {

LOGGER.warn("【参数targetDir为空】");

throw new NullArgumentException("targetDir");

}

try {

return FTPClientUtil.copy(connectServer(), sourceFile, fileSystemProperties.getProjectWorkingDirectory()

+ File.separator + targetDir);

} catch (Exception e) {

LOGGER.error("【文件拷贝失败】", e);

throw new RuntimeException("文件拷贝失败");

}

}

}

下面也给出我测试的时候,写的demo的代码(

核心代码已于2015-11-16更新,可能和上面的代码有点差别)

/**

*

*/

package com.eay.ftp;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import org.apache.commons.net.ftp.FTPClient;

import org.apache.commons.net.ftp.FTPReply;

/**

* FTP客户端工具类示例

* @author ll

*

* @version $id:FTPClientExample.java,v 0.1 2015年11月13日 上午11:32:24 ll Exp $

*/

public class FTPClientExample {

/** FTP客户端实例 */

private FTPClient ftpClient;

/**

* 私有构造器

*/

private FTPClientExample() {

}

/**

* 内部类维护单例,防止并发问题

* @author luolin

*

* @version $id:FTPClientExample.java,v 0.1 2015年11月13日 下午2:34:08 luolin Exp $

*/

private static class SingletonFactory {

private static FTPClientExample instance = new FTPClientExample();

}

/**

* 获取实例

* @return {@link FTPClientExample}

*/

public static FTPClientExample getInstance() {

return SingletonFactory.instance;

}

/**

* 连接文件服务器

* @param addr 文件服务器地址

* @param port 端口

* @param username 用户名

* @param password 密码

* @throws Exception

*/

public void connect(String addr, int port, String username, String password) throws Exception {

ftpClient = new FTPClient();

// 连接

ftpClient.connect(addr, port);

// 登录

ftpClient.login(username, password);

ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

// 判断文件服务器是否可用??

if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {

ftpClient.disconnect();

}

}

/**

* 连接文件服务器

* @param addr 文件服务器地址

* @param port 端口

* @param username 用户名

* @param password 密码

* @param workingDirectory 目标连接工作目录

* @throws Exception

*/

public void connect(String addr, int port, String username, String password, String workingDirectory)

throws Exception {

ftpClient = new FTPClient();

// 连接

ftpClient.connect(addr, port);

// 登录

ftpClient.login(username, password);

ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

// 判断文件服务器是否可用??

if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {

ftpClient.disconnect();

}

changeWorkingDirectory(workingDirectory);

}

/**

* 关闭连接,使用完连接之后,一定要关闭连接,否则服务器会抛出 Connection reset by peer的错误

* @throws IOException

*/

public void closeConnection() throws IOException {

ftpClient.disconnect();

}

/**

* 切换工作目录

* @param directory 目标工作目录

* @throws IOException

*/

public void changeWorkingDirectory(String directory) throws IOException {

// 切换到目标工作目录

if (!ftpClient.changeWorkingDirectory(directory)) {

ftpClient.makeDirectory(directory);

ftpClient.changeWorkingDirectory(directory);

}

}

/**

* @param file 上传的文件或文件夹

* @throws Exception

*/

public void upload(File file) throws Exception {

if (file == null) {

throw new RuntimeException("上传文件为空");

}

// 是文件,直接上传

if (!file.isDirectory()) {

storeFile(new File(file.getPath()));

return;

}

ftpClient.makeDirectory(file.getName());

ftpClient.changeWorkingDirectory(file.getName());

// 文件夹,递归上传所有文件

for (File item : file.listFiles()) {

if (!item.isDirectory()) {

storeFile(item);

continue;

}

upload(item);

ftpClient.changeToParentDirectory();

}

}

/**

* 删除文件

* @param fileName 要删除的文件地址

* @return true/false

* @throws Exception

*/

public boolean delete(String fileName) throws Exception {

return ftpClient.deleteFile(fileName);

}

/**

* 存储文件

* @param file {@link File}

* @throws Exception

*/

private void storeFile(File file) throws Exception {

FileInputStream input = new FileInputStream(file);

ftpClient.storeFile(file.getName(), input);

input.close();

}

/**

* 下载文件

* @param ftpFile 文件服务器上的文件地址

* @param dstFile 输出文件的路径和名称

* @throws Exception

*/

public void downLoad(String ftpFile, String dstFile) throws Exception {

File file = new File(dstFile);

FileOutputStream fos = new FileOutputStream(file);

ftpClient.retrieveFile(ftpFile, fos);

fos.flush();

fos.close();

}

/**

* 从文件服务器获取文件流

* @param ftpFile 文件服务器上的文件地址

* @return {@link InputStream}

* @throws IOException

*/

public InputStream retrieveFileStream(String ftpFile) throws IOException {

return ftpClient.retrieveFileStream(ftpFile);

}

public static void main(String[] args) throws Exception {

FTPClientExample emp = FTPClientExample.getInstance();

String addr = "192.168.111.60";

int port = 21;

String username = "admin";

String password = "admin";

emp.connect(addr, port, username, password);

// 上传文件

emp.changeWorkingDirectory("bss");

emp.upload(new File("E:\\example.txt"));

// 下载文件到指定目录

// emp.downLoad("bss\\example.txt", "E:\\example2.txt");

// 删除文件

// emp.delete("bss\\example.txt");

// 关闭连接,防止文件服务器抛出 Connection reset by peer的错误

emp.closeConnection();

}

}

java ftpclient 代码_使用FTPClient连接文件服务器并做相应操作(代码)相关推荐

  1. java ftp封装_使用FTP连接池封装Java工具类

    使用FTP连接池封装工具类 背景 早前的思路是将FTP连接的管理(对象池功能)与FTP工具类(上传下载方法)在一个工程中实现,在工具类中调用是模板类提供的模板方法, 由模板方法与对象池打交道--初始时 ...

  2. 机顶盒ttl无法输入_中兴盒子连接TTL线后无法输入代码、不跑码乱码的解决方法分享...

    连接TTL线后无法输入代码.不跑码乱码的解决方法,在群里一直会碰到一些网友询问为什么我接好了TTL线后却没有跑码或者是跑出的代码时乱码,是哪里出错了?所以今天特地开一个帖子详解一下造成这种情况的原因, ...

  3. java车间调度算法_混合算法(GA+TS)求解作业车间调度问题代码解读+完整JAVA代码...

    程序猿声 代码黑科技的分享区 前两篇文章中,我们介绍了FJSP问题,并梳理了一遍HA算法.这一篇文章对小编实现的(很乱很烂的)代码进行简单解读. 往期回顾: 代码下载请关注公众号,后台回复[FJSPH ...

  4. qml延迟代码_选择C而不是QML将您的代码减少80

    qml延迟代码 Many tools rely on web technologies like JavaScript and HTML for mobile app development. But ...

  5. ms查约束具体代码_记 Arthas 实现一次 CPU 排查与代码热更新

    简介:线上代码经常会出现 CPU 占用过高的情况,按以往经验我会使用 top 指令,进一步借助于 jstack 去查看具体信息从而进行问题排查,但基本上都逃不过需要重新发包的局面,及时是一个增量包,应 ...

  6. python快速接手别人的代码_十步教你如何接手别人的代码!

    想必在很多程序员的职业生涯中,都有过一种难以避免的状况,即接下别人的代码.而这是种怎样的体验?有人说,接手别人的代码之后我也想辞职:有人说,一个连注释都没有的代码有何灵魂可言:更有网友说,如果你恨一个 ...

  7. 如何保护python代码_如何在发布之前保护我的Python代码?

    由于Python是一种按设计进行解释的语言,而且它将代码编译为字节码(这无助于隐藏它,因为字节码更容易反转),因此没有真正安全的方法来隐藏源代码,因为它是不可恢复的,任何编程语言都是如此.在 一开始, ...

  8. python武器代码_程序员需要掌握的七种 Python 代码更易维护的武器

    检查你的代码风格 PEP 8 是 Python 代码风格规范,它规定了类似行长度.缩进.多行表达式.变量命名约定等内容.尽管你的团队自身可能也会有稍微不同于 PEP 8 的代码风格规范,但任何代码风格 ...

  9. 网页检测不到java无法打印_如果PC连接到网络打印机,如何检查java?

    根据" How Network Printing Works",它实际上取决于打印机的类型和它支持的协议.如果您知道打印机使用的IP和端口,并且您的打印机支持 SNMP(仅选择协议 ...

最新文章

  1. JUnit4.11 理论机制 @Theory 完整解读
  2. SQL Server中的执行引擎入门
  3. Hyperledger Fabric 1.0 实战开发系列 第三课 chaincode开发
  4. zeekooper集群搭建_Zookeeper与Kafka集群搭建完整教程
  5. JavaScript学习总结(六)——JavaScript判断数据类型总结
  6. 动手做个DialoGPT:生成式多轮对话模型
  7. ubuntu修改默认系统启动项
  8. 应用程序拒绝访问_让你的ASP.NET Core应用程序更安全
  9. 如果一个普通人想创业或是干点副业赚钱,应该去赚谁的钱?
  10. 蚂蚁、字节、拼多多,你的简历能通过几家?
  11. 怎么获取当前页面的URL
  12. DB9串口线定义的解析
  13. 解决Fedora14中文显示问题
  14. AI缘起 —— 达特茅斯会议
  15. 流量魔盒FlowBox 发行的代币是DMC骗局分析
  16. 基于Myrocks和spider构建分布式数据库
  17. Nginx 安装与部署配置以及Nginx和uWSGI开机自启
  18. 水浒108将(按出场顺序)
  19. DIMM DDR 区别和联系
  20. STM8S103调试PWM的踩坑过程

热门文章

  1. java byte 拓展_Java字节码文件的扩展名是( )。
  2. html场景动画,HTML5 CSS3场景动画:热情的沙漠
  3. 深度学习应用1——手势识别测试
  4. 技巧 | 如何快速生成文件清单
  5. oracle冲账语句_writeoff-冲帐英文怎么说?名词,究竟它的具体含义是什 – 手机爱问...
  6. appdmg构建dmg及原理刨析
  7. Http response详解
  8. 全国计算机等级考试二级教程素材,全国计算机等级考试二级教程MS Office高级应用--光盘内容...
  9. 每日一题/001/微积分/递推公式求定积分
  10. 时间的金钱价值(Finacial computing)