FTP介绍
FTP文件传输协议(File Transfer Protocol),用于Internet上的控制文件的双向传输,是一个应用程序。工作在TCP/IP协议族的应用层,其传输层协议是TCP协议,目的在于提高文件传输的共享性和可靠性,是基于客户/服务器模式工作的。
FTP协议
相比其他协议,如HTTP协议,FTP协议要复杂一些。与一般的C/S模型只会建立一个socket连接,这个连接同时处理服务器和客户端的连接命令和数据传输。而FTP会建立两个连接,将命令与数据分开传输,正是因为这样,提高了传输效率。
FTP使用两个端口,分别为控制端口(命令端口)和数据端口。控制端口号一般为21,数据端口一般为20。控制socket用来传输命令,数据socket用来传输数据。每一个FTP命令发送后,FTP服务器就会返回一个字符串,其中包含一个响应码和一些说明信息,其中响应码主要用于判断命令是否被成功执行了。
FTP服务器的登录和查看服务器上的文件信息
1.我们只需要下载 **easyftp-server **压缩包并解压,打开 **Ftpconsole.exe **可执行文件即可打开服务器
2.打开后界面如下,然后点击图中按钮设置服务器的连接配置和用户访问权限
3.在浏览器中连接并访问我们的服务器:在浏览器中输入服务器的IP地址+端口号,连接成功后便可实现查看、下载服务器上文件等开放权限的功能
那么,基于FTP协议的客户端和服务器端是如何进行“沟通”的?我们来一探究竟吧。
将FTP客户端和服务器端之间的“沟通”分为4个阶段:
1.启动FTP
2.建立控制连接
3.建立数据连接,并进行文件传输
4.关闭FTP
文件传输方式
1.ASCLL传输方式
假设用户正在拷贝的文件包含的简单ASCLL文本,如果我们使用的是windows系统,而运行FTP服务器的远程机上是Linux系统,那么使用ASCLL传输模式会将\r\n转为\n。当文件传输时FTP会自动调整文件的内容以便于把文件解析为另外那台计算机存储文本文件的格式。
2.二进制传输方式
二进制传输时,在拷贝任何非文本文件时,FTP会逐字拷贝,不会对这些文件进行处理。
两种传输方式的区别
相比之下,二进制传输方式会更好一些,我们经常进行传输的文件格式不单单是文本文件,可能是程序、数据库、压缩文件。ASCLL传输方式会改变我们的文件,即使不需要也会进行转译,会导致传输稍微变慢,也会损坏数据。
因此,在这里我们选用二进制传输方式实现基于FTP协议的文件上传与下载
文件上传
在用java程序实现上传文件至FTP服务器时,首当其冲我们先要实现与服务器的连接登录,当然我们需要准备一个文件输入流FileInputStream用于读取本地文件。
1.创建FTPClient对象
2.创建文件输入流,用于读取本地文件
3.连接FTP服务器
4.登录
FTPClient ftpClient=new FTPClient();
//创建文件输入流,用于读取本地文件
FileInputStream localIn = new FileInputStream("E:\\photo\\192-168-137-1.jpg"))
//连接FTP服务器
ftpClient.connect("192.168.254.176",21);
//登录
ftpClient.login("root", "root");
登录成功后,我们继续实现将本地文件上传到服务器的后续步骤
1.存储前设置文件类型
2.存储文件:
参数1:FTP服务器的存储位置(目录+文件)
参数2:本地的文件输入流
//存储文件(将本地文件上传至FTP服务器)
//参数1:FTP服务器的存储位置(目录+文件)
//参数2:本地的文件输入流
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//存储前设置文件类型
ftpClient.storeFile("cat.jpg", localIn);//存储
至此,我们就成功的将本地的一个.jpg格式的文件成功上传到了FTP服务器。如果我们要切换在服务器上的存储目录,只需要完成如下步骤:
//切换至指定目录
boolean isChange = ftpClient.changeWorkingDirectory("/指定目录");
if(!isChange) {
ftpClient.makeDirectory("/指定目录");
isChange=ftpClient.changeWorkingDirectory("/指定目录");
}
下载文件
- 连接并登录
2.切换至工作目录
3.下载文件
public class DownLoad {
public static void main(String[] args) {
String downloadFileName = "cat.jpg";
FTPClient ftpClient = new FTPClient();
try (FileOutputStream out = new FileOutputStream("E:\\a\\" + downloadFileName)) {
// 连接并登录
ftpClient.connect("192.168.254.176", 21);
ftpClient.login("root", "root");
// 切换至工作目录
ftpClient.changeWorkingDirectory("Excel");
//存储前设置文件类型
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
boolean isRetrieve = ftpClient.retrieveFile(downloadFileName, out);
System.out.println("下载成功?" + isRetrieve);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
获取FTP服务器下指定目录的所有文件
完成了文件的上传与下载,我们接下来再通过一个案例:实现获取FTP服务器下指定目录的所有文件,加深一下对FTP协议的理解。
//获取FTP服务器下指定目录的所有文件
public class FTPFileList {
public static void main(String[] args) {
//FTP客户端对象
FTPClient ftpClient=new FTPClient();
try {
//连接并登录
ftpClient.connect("192.168.254.176", 21);
ftpClient.login("root", "root");
//切换至工作目录
boolean isChange = ftpClient.changeWorkingDirectory("Excel");
System.out.println("切换目录:"+isChange);
//日期格式切换
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
//获取该目录下的所有文件
FTPFile[] files=ftpClient.listFiles();
for(FTPFile f: files) {
System.out.println("文件名称:"+f.getName());
//获取文件创建时间
Date createDate= f.getTimestamp().getTime();
//日期格式化
String createDateStr=sdf.format(createDate);
System.out.println("创建时间:"+createDateStr);
//文件大小
System.out.println("文件大小:"+f.getSize());
//上传用户
System.out.println("上传用户:"+f.getUser());
System.out.println();
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//断开连接
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
如果本文章对你有帮助,记得留下点赞哦,谢谢!
版权归原作者 小田同学卷代码 所有, 如有侵权,请联系我们删除。