java连接 ftp_Java使用FTPClient连接文件服务器并做相应操作(代码)

/**

*

*/

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的代码

/**

*

*/

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();

}

}

commons-net

commons-net

3.3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值