文件传送协议(FTP协议)
一、FTP协议的概述
- 文件传送协议(File Transfer Protocol)是互联网上使用的最广泛的文件传输协议,用于Internet上的控制文件的双向传输。
- TP提供交互式的访问,允许客户指明文件类型与格式,并允许文件具有存取权限。
- FTP屏蔽了各计算机系统的细节,因而适合于在异构网络中计算机之间传送文件
二、FTP协议的特点
- 文件传送协议FTP只提供文件传送的一些基本的服务,它使用TCP可靠的运输方式。
- FTP的主要功能是减少或消除在不同操作系统下处理文件的不兼容性。
- FTP使用客户服务器方式。一个FTP服务器进程可同时为多个客户进程提提供服务,FTP的服务器进程由二大部分组成:一个是主进程,负责接受新的请求;另外有诺干个从属进程,负责处理单个请求。实现FTP文件上传与下载的两种方式
三、 FTP的工作过程
1.FTP使用的两个TCP连接(如下图所示)
- FTP使用客户服务器方式。一个 FTP服务器进程可同时为多个客户进程提供服务。FTP的服务器进程由两大部分组成:一个主进程,负责接受新的请求;另外由若干个从属进程,负责处理单个请求。
- 主进程工作步骤如下:
①打开熟知端口(端口号为21),使客户进程能够连接上。
②等待客户进程发出连接请求。
③启动从属进程来处理客户进程发来的请求。从属进程对客户进程的请求处理完毕后即 终止,但从属进程在运行期间根据需要还可能创建其他一些子进程。
④回到等待状态,继续接受其他客户进程发来的请求。主进程与从属进程的处理是并发 地进行。
四、实现FTP文件上传与下载的两种方式
- 通过JDK自带的API实现
- 通过Apache提供的API实现
代码实现前的准备工作
首先打开Ftpconsole.exe文件,找到账号管理,并新建一个用户
在新建账号中输入自己的用户名以及密码,并选择你所需要的权限。打开Ftpconsole.exe后你能够看见主机名称和主机IP,以及FTP服务端口和Web服务端口
可以看到主机IP有三个,那是因为电脑中含有虚拟机,可以在控制面板中找到网络和 Internet选择网络连接,右键禁用虚拟机
准备好这些工作后,在文件夹下导入所需要用的jar包
代码实现过程
一、连接FTP服务器,显示文件列表
package com.apesource.demo;
import java.io.IOException;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
//连接FTP服务器,显示文件列表
public class Demo01 {
public static void main(String[] args) {
try {
//第一步:连接FTP服务器并验证用户名密码
FTPClient ftpClient = new FTPClient();
ftpClient.connect("192.168.142.1",21); //ftpClient.connect("本机地址",21)
ftpClient.login("xxx", "*****"); //ftpClient.login(userName,PassWord)
//第二步
boolean isChange = ftpClient.changeWorkingDirectory("xxx");
if(isChange) {
//切换成功 显示XXX目录下的所有文件
SimpleDateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日");
//获取当前目录中的所有文件
FTPFile[] ftpfileList = ftpClient.listFiles();
for(FTPFile file:ftpfileList) {
//文件名称中包含中文乱码
String fileName = file.getName();
fileName = new String(fileName.getBytes("iso-8859-1"),"gb2312"); //防止中文乱码
System.out.println("文件名称:"+fileName);
Date creatdate = file.getTimestamp().getTime();
System.out.println("创建时间:"+fmt.format(creatdate));
System.out.println("文件大小:"+file.getSize()+"字节");
}
}else {
//创建指定文件
ftpClient.makeDirectory("xxx");
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、基于FTP协议的文件上传
package com.apesource.demo;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTPClient;
//基于FTP协议的文件上传
public class Demo02 {
public static void main(String[] args) {
//创建基于FTP协议访问文件服务器的客户端对象
FTPClient ftpClient = new FTPClient();
try (FileInputStream in = new FileInputStream("C:\\Users\\Pictures\\xxx.jpg")){
//第一步:连接FTP服务器并验证用户名密码
ftpClient.connect("192.168.142.1",21);
ftpClient.login("XXX", "******");
//第二步:切换个人目录
boolean isChange = ftpClient.changeWorkingDirectory("xxx");
if(!isChange) {
//切换个人目录
//目录下的文件名称必须一致
ftpClient.makeDirectory("xxx");
//切换
ftpClient.changeWorkingDirectory("xxx");
}
//第三步 文件上传
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
//存文件至FTP服务器
//参数一:FTP文件的保存名称
//参数二:本地文件输入流
boolean isStore = ftpClient.storeFile(System.currentTimeMillis()+".jpg", in);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
三、基于FTP协议的文件下载
package com.apesource.demo;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTPClient;
//基于FTP协议的文件下载
public class Demo03 {
public static void main(String[] args) {
//创建基于FTP协议访问文件服务器的客户端对象
FTPClient ftpClient = new FTPClient();
try(FileOutputStream out = new FileOutputStream("C:\\Users\\Pictures\\xxx\\"+System.currentTimeMillis()+".jpg")) {
//第一步:连接FTP服务器并验证用户名密码
ftpClient.connect("192.168.142.1",21);
ftpClient.login("xxx", "******");
//第二步:切换至个人目录
boolean isChange = ftpClient.changeWorkingDirectory("xxx");
//第三步:下载指定文件
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); //文件类型
boolean isRetrieve = ftpClient.retrieveFile("bbb.jpg",out);
System.out.println("下载成功?"+isRetrieve);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//断开连接
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在书写代码中会出现异常,这个时候我们需要使用try/catch块进行异常处理,或直接抛出异常。