Java中FTP服务器实现文件的列表展示、文件的上传与下载

文件传送协议(FTP协议)

一、FTP协议的概述

  1. 文件传送协议(File Transfer Protocol)是互联网上使用的最广泛的文件传输协议,用于Internet上的控制文件的双向传输。
  2. TP提供交互式的访问,允许客户指明文件类型与格式,并允许文件具有存取权限。
  3. FTP屏蔽了各计算机系统的细节,因而适合于在异构网络中计算机之间传送文件

 二、FTP协议的特点

  1. 文件传送协议FTP只提供文件传送的一些基本的服务,它使用TCP可靠的运输方式。
  2. FTP的主要功能是减少或消除在不同操作系统下处理文件的不兼容性。
  3. FTP使用客户服务器方式。一个FTP服务器进程可同时为多个客户进程提提供服务,FTP的服务器进程由二大部分组成:一个是主进程,负责接受新的请求;另外有诺干个从属进程,负责处理单个请求。实现FTP文件上传与下载的两种方式

三、 FTP的工作过程

1.FTP使用的两个TCP连接(如下图所示)

  1. FTP使用客户服务器方式。一个 FTP服务器进程可同时为多个客户进程提供服务。FTP的服务器进程由两大部分组成:一个主进程,负责接受新的请求;另外由若干个从属进程,负责处理单个请求。
  2. 主进程工作步骤如下:

                ①打开熟知端口(端口号为21),使客户进程能够连接上。

                ②等待客户进程发出连接请求。

                ③启动从属进程来处理客户进程发来的请求。从属进程对客户进程的请求处理完毕后即                      终止,但从属进程在运行期间根据需要还可能创建其他一些子进程。

                ④回到等待状态,继续接受其他客户进程发来的请求。主进程与从属进程的处理是并发                      地进行。

四、实现FTP文件上传与下载的两种方式 

  1. 通过JDK自带的API实现
  2. 通过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块进行异常处理,或直接抛出异常。