【日常开发之FTP】windows开启FTP、Java实现FTP文件上传下载
- FTP前言
- FTP是什么?
- FTP两种模式
- Windows开启FTP
- FTP windows 配置
- 防火墙配置
- Java部分
- Maven配置
- 创建FTPClient
- 注意
FTP前言
FTP是什么?
FTP是一个专门进行文件管理的操作服务,一般来讲可以在任意的操作系统之中进行配置,但是如果考虑到简便性,一般来讲可以直接在Linux系统下进行安装。
FTP (File Transfer Protocol、文件传输协议)是TCP/IP协议中的一部分,属于应用层协议。使用FTP最主要的功能是对文件进行管理,所以在FTP内部对于文件支持有两种传输模式:文本模式(ASCII、默认)和二进制模式(Binary),通常文本文件使用ASCIl模式,而对于图片、视频、声音、压缩等文件则会使用二进制的方式进行传输。
FTP的操作一般是分为服务端以及客户端两个组成部分,客户端需要通过特定的FTP服务进行服务器的连接(大部分的FTP服务器上都是需要进行用户登录认证的)。
FTP两种模式
如果要进行FTP文件的管理,则客户端一定要与FTP服务器进行连接,在FTP中每一次通讯实际上都需要有两个连接存在,一个连接专门用于传输FTP命令、另外一个连接负责数据传送,所以在FTP中一般会支持两种不同的工作模式:一种是Standard模式(也被称为PORT模式),另外一种是Passive (也被称为PASV模式),这两种模式的概念如下:
PORT主动模式
当客户端与服务端连接后,客户端会打开一个新的本地端口,随后将此端口告诉给FTP服务端,这样FTP服务端就会主动的连接到FTP客户端公布的端口,随后进行数据传送。
PASV被动模式
FTP在定义的时候就公布了一个操作端口(一般为21端口),这样当客户端连接之后会明确的知道该操作端口并且进行数据传送。
在实际的FTP运行机制之中,如果要想通过FTP服务进行操作,则一般会使用被动模式,在所有的系统中几乎都会存在有防火墙的概念,如果要考虑到客户端的方便使用的话,被动的模式会更加的合理。
Windows开启FTP
进入控制面板–》程序–》启用或关闭windows功能
开启FTP服务勾选红色方框内的选项点击确定
FTP windows 配置
win + R 输入 inetmgr
进入如下界面
箭头指向点击–》右键添加FTP站点
站点名称:FTP
物理路径:选择你FTP开放的路径
注意:这个ip地址要配你暴露出去的地址,如果是作为FTP服务器,要保证这个ip其他节点能够ping通
选择无ssl
这里的用户可以指定用户也可以选择所有用户
权限要写读写,不然无法进行上传下载
双击左侧FTP
查看各项信息是否正确
防火墙配置
控制面板–》系统安全–》Windows Defender 防火墙–》允许的应用中勾选FTP
点击我的电脑右键选择管理右键用户,选择新用户添加
Java部分
Maven配置
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.8.0</version>
</dependency>
创建FTPClient
上传
public static void main(String[] args) throws IOException {
String server = "192.168.0.121";
int port = 21;
String user = "ftp";
String pass = "123456";
FTPClient ftp = new FTPClient();
FileInputStream fileInputStream =null;
try {
ftp.connect(server, port);
ftp.login(user, pass);
//这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据
ftp.enterLocalPassiveMode();
// 二进制文件传输
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.setControlEncoding("UTF-8");
ftp.setBufferSize(2048);
// 上传文件的路径
String remoteFilePath = "/WorkSpace/啊啊啊.csv";
//远程路径一定要进行编码否则上传失败
remoteFilePath = new String(remoteFilePath.getBytes("GBK"), "iso-8859-1");
// 本地文件的路径
String localFilePath = "/WorkSpace/Test/啊啊啊.csv";
// 使用storeFile上传文件
if (ftp.storeFile(remoteFilePath,fileInputStream = new FileInputStream(new File(localFilePath)))) {
System.out.println("文件上传成功");
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (ftp.isConnected()) {
ftp.logout();
ftp.disconnect();
}
//手动关流
if(fileInputStream!=null){
fileInputStream.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
下载
//我这边项目运行是在D盘所以不需要加盘符
//remoteFile FTP路径 /WorkSpace/Test/啊啊啊.csv
//localFile 要存储到本地的路径
private static void download(FTPClient ftpClient, String remoteFile, String localFile) {
OutputStream outputStream = null;
try {
ftpClient.enterLocalPassiveMode();
outputStream = Files.newOutputStream(Paths.get(localFile));
// ftp默认使用ISO-8859-1编码格式,所以这里需要转换为ISO-8859-1,“解决文件名为中文时,下载后为空文件的问题”
String remoteFileName = new String(remoteFile.getBytes("GBK"), StandardCharsets.ISO_8859_1);
ftpClient.retrieveFile(remoteFileName, outputStream);
} catch (IOException ex) {
System.out.println("DownLoad Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
ftpClient.disconnect();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
注意
在开发过程中遇到了一些问题,各位在用时可能会遇到,在上传时遇到上传失败,我这边是因为文件名是中文的问题
转码一下就好了
remoteFilePath = new String(remoteFilePath.getBytes("GBK"), StandardCharsets.ISO_8859_1);
然后就是下载时发现文件为空文件
还是转码一下就好了
String remoteFileName = new String(remoteFile.getBytes("GBK"), StandardCharsets.ISO_8859_1);