主要演示Java整合FTP后的一些常用基本操作;
为方便操作,直接使用Maven运行测试;
在配置文件中引入FTP操作依赖(FTPClient):

1
2
3
4
5
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>

然后直接上代码吧,
运行类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import org.apache.commons.net.ftp.FTPClient;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Scanner;

@Component
@SpringBootApplication
public class App {
public static void main(String[] args) {
FTPClient ftpClient = new FTPClient();

InitFTP initFTP = new InitFTP();
System.out.println("退出请输入exit,输入其他字符继续操作");
while (!"exit".equals(new Scanner(System.in).next())) {
initFTP.initFtpClient(ftpClient);
System.out.println("请输入操作(上传、下载、删除、移动、读取、写入):");
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
if ("上传".equals(next)) {
UploadFTP uploadFTP = new UploadFTP();
String fileName = "ahzoo.txt";
String pathName = "\\ftpPath";
String originFilename = "E:\\ouo\\ouo.txt";
uploadFTP.uploadFile(pathName, fileName, originFilename, ftpClient);
} else if ("下载".equals(next)) {
DownloadFTP downloadFTP = new DownloadFTP();
// String fileName = "ahzoo.md";
String fileName = null;
String pathName = "\\ftpPath";
String downloadPath = "E:\\ahzoo";
downloadFTP.downLoadFTP(pathName, fileName, downloadPath, ftpClient);
} else if ("删除".equals(next)) {
DeleteFTP deleteFTP = new DeleteFTP();
// String fileName = "ahzoo.md";
String fileName = null;
String pathName = "\\test";
deleteFTP.deleteFTP(pathName, fileName, ftpClient);
} else if ("移动".equals(next)) {
MoveFTP moveFTP = new MoveFTP();
String fileName = "ahzoo.txt";
String pathName = "\\ftpPath";
String moveName = "move.txt";
String movePath = "\\ouo";
moveFTP.moveFTP(pathName, fileName, movePath, moveName, ftpClient);
} else if ("读取".equals(next)) {
ReadFTP readFTP = new ReadFTP();
String fileName = "ahzoo.txt";
String pathName = "\\ftpPath";
readFTP.readFTP(pathName, fileName, ftpClient);
} else if ("写入".equals(next)) {
WriteFTP writeFTP = new WriteFTP();
String fileName = "测试.txt";
String pathName = "\\ftpPath";
String contentText = "十玖八柒654321";
writeFTP.writeFile(pathName, fileName, contentText, ftpClient);
} else {
System.out.println("输入有误");
//关闭连接
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}

}
System.out.println("退出请输入exit,输入其他字符继续操作");


}

}
}

FTP连接类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import java.io.IOException;
import java.net.MalformedURLException;
/**
* 连接FTP服务链接
*/
public class InitFTP {

//ftp服务器IP
private static final String host = "192.168.6.125";
//ftp服务器端口号默认为21
private static final Integer port = 21;
//ftp登录账号
private static final String username = "ahzoo";
//ftp登录密码
private static final String password = "123";

public void initFtpClient(FTPClient ftpClient) {
ftpClient.setControlEncoding("utf-8"); //设置编码
try {
System.out.println("正在连接FTP服务器:" + host + ":" + port);
ftpClient.connect(host, port); //连接ftp服务器
ftpClient.login(username, password); //登录ftp服务器
int replyCode = ftpClient.getReplyCode(); //是否成功登录服务器
if(!FTPReply.isPositiveCompletion(replyCode)){
System.out.println("FTP服务器连接失败:" + host + ":" + port);
}
System.out.println("FTP服务器连接成功:" + host + ":" + port);
}catch (MalformedURLException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
}

操作相关类:

上传文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import org.apache.commons.net.ftp.FTPClient;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;


public class UploadFTP {
/**
* 文件上传
* @param pathName 文件上传到ftp服务器的路径
* @param fileName 文件上传到ftp服务器的名称
* @param originPath 要上传文件所在的路径(绝对路径)
**/
public void uploadFile(String pathName, String fileName, String originPath, FTPClient ftpClient){
InputStream inputStream = null;
try{
System.out.println("文件传输中");
inputStream = new FileInputStream(new File(originPath));//将文本数据转换为输入流

ftpClient.enterLocalPassiveMode(); //设置被动模式传输
ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);//以二进制文件形式输入
ftpClient.makeDirectory(pathName);//在ftp服务器创建目标路径
ftpClient.changeWorkingDirectory(pathName);//切换到目标路径
ftpClient.enterLocalPassiveMode();//开启端口
ftpClient.storeFile(fileName, inputStream);//开始上传,inputStream表示数据源。
//ftpClient.storeFile(new String(fileName.getBytes("UTF-8"),"ISO-8859-1") inputStream);


System.out.println("文件上传操作完成");
}catch (Exception e) {
System.out.println("文件上传失败");
e.printStackTrace();
}finally{
//关闭连接
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
if(null != inputStream){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

下载文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class DownloadFTP {
/**
* 文件下载(暂未实现下载路径内子文件中文件功能)
* @param pathName 要下载文件所在ftp路径
* @param fileName 要下载文件所在ftp的文件名
* @param downloadPath 文件下载后保存的路径
* @param ftpClient FTPClient对象
*/
public void downLoadFTP(String pathName, String fileName, String downloadPath, FTPClient ftpClient) {

OutputStream outputStream = null;
try {
ftpClient.changeWorkingDirectory(pathName);// 跳转到文件目录
ftpClient.enterLocalPassiveMode(); //设置被动模式传输

if (fileName != null && fileName != "") {
//文件名不为空,下载指定文件
File filePath = new File(downloadPath);
if (!filePath.exists()) {
filePath.mkdir();//目录不存在,创建目录
}
outputStream = new FileOutputStream(new File(downloadPath + File.separator + fileName));
ftpClient.retrieveFile(fileName, outputStream);
System.out.println("下载操作完成");
} else {
FTPFile[] files = ftpClient.listFiles();//获取目录下文件集合
//文件名为空,下载路径下所有文件(不包含文件夹)
for (FTPFile file : files) {
File filePath = new File(downloadPath);
if (!filePath.exists()) {
filePath.mkdir();//目录不存在,创建目录
}
File downloadFile = new File(downloadPath + File.separator + file.getName());
outputStream = new FileOutputStream(downloadFile);
ftpClient.retrieveFile(file.getName(), outputStream);

System.out.println("下载操作完成:" + downloadFile);
}
}

} catch (Exception e) {
System.out.println("下载失败");
e.printStackTrace();
} finally {
//关闭连接
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
if(null != outputStream){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

}

}

删除:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

import java.io.File;
import java.io.IOException;

public class DeleteFTP {
/**
* 文件删除 (暂未实现删除路径内子文件夹功能)
* @param pathName 要删除文件/目录所在ftp路径
* @param fileName 要删除文件所在ftp的文件名
* @param ftpClient FTPClient对象
*/
public void deleteFTP(String pathName, String fileName, FTPClient ftpClient) {

try {
ftpClient.changeWorkingDirectory(pathName);// 跳转到文件目录
ftpClient.enterLocalPassiveMode(); //设置被动模式传输
if (fileName != null && fileName != "") {
//文件名不为空,删除指定文件
ftpClient.deleteFile(pathName + File.separator + fileName);
System.out.println("删除成功");
} else {
//文件名为空,删除路径下所有文件
System.out.println("正在删除");
//删除文件
FTPFile[] files = ftpClient.listFiles();//获取目录下文件集合
for (FTPFile file : files) {

if (file.isFile()) {
//判断为文件,直接删除
ftpClient.deleteFile(pathName + File.separator + file.getName());
System.out.println(file + ":已完成删除操作");
}
if (file.isDirectory()) {
/*有点问题,建议使用线程优化

//判断是文件夹,递归删除子文件夹内文件
deleteFTP(pathName + File.separator + file.getName(), null, ftpClient);
*/
}
}
//删除文件夹
ftpClient.removeDirectory(pathName);
System.out.println("删除操作完成");
}
} catch (Exception e) {
System.out.println("删除失败");
e.printStackTrace();
} finally {
//关闭连接
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
}

}
}

移动:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

import java.io.File;
import java.io.IOException;

public class MoveFTP {
/**
* 文件移动/重命名
* @param pathName 要移动文件所在ftp路径
* @param fileName 要移动文件所在ftp的文件名
* @param movePath 文件移动后的路径
* @param moveName 文件移动后的文件名(与源文件一致时实现只移动不重命名,不一致则实现了移动+重命名)
* @param ftpClient FTPClient对象
*/
public void moveFTP(String pathName, String fileName, String movePath, String moveName, FTPClient ftpClient) {
try {
ftpClient.enterLocalPassiveMode(); //设置被动模式传输
if (!ftpClient.changeWorkingDirectory(movePath)) {
//跳转到目标路径失败时创建目标目录
ftpClient.makeDirectory(movePath);
}
if (moveName != null && moveName != "") {
ftpClient.changeWorkingDirectory(pathName);// 跳转回需要进行操作的目录
//移动后的文件名不为空,移动目标文件
//ftpClient.rename(旧文件名, 新路径)
ftpClient.rename(fileName, movePath + File.separator + moveName);
System.out.println("文件移动操作已完成:" + movePath + File.separator + moveName);
} else {
//移动后的文件名为空,移动目标路径所有文件

ftpClient.changeWorkingDirectory(pathName);// 跳转回需要进行操作的目录
FTPFile[] files = ftpClient.listFiles();//获取目录下文件集合

for (FTPFile file : files) {
ftpClient.rename(file.getName(), movePath + File.separator + file.getName());
System.out.println("移动操作完成:" + file.getName());
}
}

} catch (Exception e) {
System.out.println("移动失败");
e.printStackTrace();
} finally {
//关闭连接
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
}

}

}



读取:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

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

import java.io.*;

public class ReadFTP {
/**
* 文件读取(暂未实现读取路径内子文件中文件功能)
* @param pathName 要读取文件所在ftp路径
* @param fileName 要读取文件所在ftp的文件名
* @param ftpClient FTPClient对象
*/
public void readFTP(String pathName, String fileName, FTPClient ftpClient) {

InputStream inputStream = null;
BufferedReader reader = null;
try {
System.out.println(pathName);
ftpClient.changeWorkingDirectory(pathName);// 跳转到文件目录
ftpClient.enterLocalPassiveMode(); //设置被动模式传输

if (fileName != null && fileName != "") {
//文件名不为空,读取指定文件
inputStream = ftpClient.retrieveFileStream(fileName);
reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String fileL;
StringBuffer buffer = new StringBuffer();
while(((fileL=reader.readLine()) != null)){
buffer.append(fileL);
}
System.out.println(fileName + ":" + buffer.toString());

} else {
FTPFile[] files = ftpClient.listFiles();//获取目录下文件集合
//文件名为空,下载路径下所有文件(不包含文件夹)
System.out.println(files);
for (FTPFile file : files) {
System.out.println(file.getName());
inputStream = ftpClient.retrieveFileStream(file.getName());
System.out.println(inputStream);
reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String fileL = null;
StringBuffer buffer = new StringBuffer();

while(((fileL=reader.readLine()) != null)){
buffer.append(fileL + "\n");
}
System.out.println(file + ":" + buffer.toString());
}
}

} catch (Exception e) {
System.out.println("读取失败");
e.printStackTrace();
} finally {
//关闭连接
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
//retrieveFileStream使用了流,需要释放一下,不然会返回空指针
ftpClient.completePendingCommand();
}catch(IOException e){
e.printStackTrace();
}
}
if(null != inputStream){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != reader) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

}

}

写入:

写入操作与上传操作基本一致,唯一不同的就是写入操作是将文本转换为流,上传是读取文件后转换为流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import org.apache.commons.net.ftp.FTPClient;

import java.io.*;

public class WriteFTP {
/**
* 文本写入
* @param pathName 文本写入到ftp服务器的路径
* @param fileName 文本写入到ftp服务器的名称
* @param contentText 要写入的文本数据
**/
public void writeFile(String pathName, String fileName, String contentText, FTPClient ftpClient){
InputStream inputStream = null;
try{
System.out.println("开始写入操作");
inputStream = new ByteArrayInputStream(contentText.getBytes());//将文本数据转换为输入流,通过getBytes()方法避免中文乱码

ftpClient.enterLocalPassiveMode(); //设置被动模式传输
ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);//以二进制文件形式输入
ftpClient.makeDirectory(pathName);//在ftp服务器创建目标路径
ftpClient.changeWorkingDirectory(pathName);//切换到目标路径
ftpClient.enterLocalPassiveMode();//开启端口
ftpClient.storeFile(fileName, inputStream);//开始写入,inputStream表示数据源。

System.out.println("文本写入操作完成");
}catch (Exception e) {
System.out.println("文本写入失败");
e.printStackTrace();
}finally{
//关闭连接
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
if(null != inputStream){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}