文件传输协议(File Transfer Protocol,FTP)是用于在网络上进行文件传输的一套标准协议,它工作在 OSI 模型的第七层, TCP 模型的第四层, 即应用层, 使用 TCP 传输而不是 UDP, 客户在和服务器建立连接前要经过一个“三次握手”的过程, 保证客户与服务器之间的连接是可靠的, 而且是面向连接, 为数据传输提供可靠保证。
FTP允许用户以文件操作的方式(如文件的增、删、改、查、传送等)与另一主机相互通信。然而, 用户并不真正登录到自己想要存取的计算机上面而成为完全用户, 可用FTP程序访问远程资源, 实现用户往返传输文件、目录管理以及访问电子邮件等等, 即使双方计算机可能配有不同的操作系统和文件存储方式。
1.1工作流程
在传输文件时,FTP 客户端程序先与服务器建立连接,然后向服务器发送命令。服务器收到命令后给予响应,并执行命令。FTP 协议与操作系统无关,任何操作系统上的程序只要符合 FTP 协议,就可以相互传输数据
1.2工作模式
FTP支持两种模式:Standard (PORT方式,主动方式),Passive (PASV,被动方式)
1.3传输方式
FTP的传输有两种方式:ASCII、二进制
在自己的电脑上可以开启一个ftp服务用于测试。
打开控制面板—>程序—>启动或关闭windows功能
找到互联网信息服务勾选✔其中的ftp服务器,web管理,万维网服务。
系统就会安装IIS服务管理器了,安装过程可能需要等待几分钟。
回到电脑桌面,右击“计算机”,点击 管理,进入计算机管理界面。在这里,我们就可以看到刚刚添加的IIS服务,接下来的操作就像我们在VPS主机上添加网站差不多的操作步骤了。选中IIS服务——>网站——>右键添加FTP站点
设置ftp基本信息。路径为远程连接的工作路径
选取本机的IP地址,SSL如果不涉密可以选无。
这里权限先这样设置之后再修改,点击完成即可。
保存后在此后即可看到添加的ftp服务。可以这样开启多个。
注意:
要想通过java程序连接FTP在这里我新建了一个FTP的用户,新建一个用户ftptest,密码:123456,如下所示
这里注意一定要把√取消掉确定完成新建,之后修改FTP服务器设置,添加这个特定用户。
点击创建的ftp名称—>ftp身份验证—>修改身份认证,禁止匿名身份
返回最开始的页面,添加刚才创建的用户,如果创建用户对勾选着可能添加不成功。
输入刚才新建的用户名和密码,完成
如何测试刚才新建的用户是否有效嘞有好多种方法常用的是CMD命令行和下面介绍的这种
打开我的电脑在最上面输入
ftp://+FTP之前设置的IP地址
我的是ftp://192.168.10.11/回车
输入用户和密码即可登录
注意:如果输入后弹出FTP文件夹错误,需要查看一下防火墙是否放行FTP服务器
解决方式:
打开防火墙,点击允许应用或功能通过Windows Defender防火墙
找到FTP服务器并勾选,然后点击确定
org.apache.commons.net提供了对FTP的开发,引入以下依赖
commons-net commons-net 3.9.0
3.1ftp工具类
连接ftp服务
@Slf4jpublic class FtpClient { private static String FTP_IP; private static Integer FTP_PORT; private static String FTP_USER; private static String FTP_PASSWORD; private static String FTP_PATH; private static String FTP_DRIVELETTER; private static FTPClient ftpClient; static { try { // 根据该类的class文件获取到yaml文件 Yaml yaml = new Yaml(); URL resource = FtpClient.class.getClassLoader().getResource("application-dev.yml"); assert resource != null; // 把yaml文件加载到对象中 Object obj = yaml.load(new FileInputStream(resource.getFile())); // 解析对象中的属性并赋值 JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(obj)); JSONObject ftp = jsonObject.getObject("fanhai", JSONObject.class).getObject("ftp", JSONObject.class); FTP_IP = String.valueOf(ftp.get("ip")); FTP_PORT = Integer.valueOf(String.valueOf(ftp.get("port"))); FTP_USER = String.valueOf(ftp.get("username")); FTP_PASSWORD = String.valueOf(ftp.get("password")); } catch (Exception e) { e.printStackTrace(); } } public static FTPClient getFtpConnection() { ftpClient = new FTPClient(); try { //连接 ftpClient.connect(FtpClient.FTP_IP, FtpClient.FTP_PORT); //设置编码 ftpClient.setControlEncoding("UTF-8"); //设置传输文件类型 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); //登录 ftpClient.login(FtpClient.FTP_USER, FtpClient.FTP_PASSWORD); if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { log.info("==============未连接到FTP,用户名或密码错误================="); //拒绝连接 ftpClient.disconnect(); } else { log.info("==============连接到FTP成功================="); } } catch (SocketException e) { e.printStackTrace(); log.info("==============FTP的IP地址错误=============="); } catch (IOException e) { e.printStackTrace(); log.info("==============FTP的端口错误=============="); } return ftpClient; } public static void closeConnect() { log.warn("关闭ftp服务器"); try { if (ftpClient != null) { ftpClient.logout(); ftpClient.disconnect(); } } catch (Exception e) { e.printStackTrace(); } }}
ftp工具类,进行文件的上传、下载操作
public class FtpUtils { public static boolean uploadFile(String ftpPath, String uploadFileName, InputStream input) { boolean issuccess = false; FTPClient ftpClient = null; try { ftpClient = FtpClient.getFtpConnection(); //切换到工作目录 if (!ftpClient.changeWorkingDirectory(ftpPath)) { ftpClient.changeWorkingDirectory("/"); String[] dirs = ftpPath.split("/"); for (String dir : dirs) { ftpClient.makeDirectory(dir); ftpClient.changeWorkingDirectory(dir); } } ftpClient.enterLocalPassiveMode();//工作模式被动 //文件写入 远程文件名;输入流 boolean storeFile = ftpClient.storeFile(uploadFileName, input); if (!storeFile) { return issuccess; } input.close(); ftpClient.logout(); issuccess = true; } catch (IOException e) { e.printStackTrace(); } finally { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException ioe) { } } } return issuccess; } private String inputStreamToString(InputStream inputStream) { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); StringBuffer stringBuffer = new StringBuffer(); String oneLine = ""; try { while ((oneLine = bufferedReader.readLine()) != null) { stringBuffer.append(oneLine); } return stringBuffer.toString(); } catch (IOException e) { e.printStackTrace(); } return null; }}
来源地址:https://blog.csdn.net/weixin_44486583/article/details/130319858