阿里云服务器+ftp文件操作+基于Centos7的vsftpd配置

路径问题:一定要注意此位置是否需要加入"/"

文件上传方式:被动模式

vsftp完整配置:

#
# The default compiled in settings are fairly paranoid. This sample file
# loosens things up a bit, to make the ftp daemon more usable.
# Please see vsftpd.conf.5 for all compiled in defaults.
#
# READ THIS: This example file is NOT an exhaustive list of vsftpd options.
# Please read the vsftpd.conf.5 manual page to get a full idea of vsftpd's
# capabilities.
#
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
# When SELinux is enforcing check for SE bool ftp_home_dir
local_enable=YES
#
# Uncomment this to enable any form of FTP write command.
write_enable=YES
#
# Default umask for local users is 077. You may wish to change this to 022,
# if your users expect that (022 is used by most other ftpd's)
local_umask=022
#local_umask=002 #
# Uncomment this to allow the anonymous FTP user to upload files. This only
# has an effect if the above global write enable is activated. Also, you will
# obviously need to create a directory writable by the FTP user.
# When SELinux is enforcing check for SE bool allow_ftpd_anon_write, allow_ftpd_full_access
#anon_upload_enable=YES
#
# Uncomment this if you want the anonymous FTP user to be able to create
# new directories.
#允许用户创建目录
#anon_mkdir_write_enable=YES
#
# Activate directory messages - messages given to remote users when they
# go into a certain directory.
dirmessage_enable=YES
#
# Activate logging of uploads/downloads.
xferlog_enable=YES
#
# Make sure PORT transfer connections originate from port 20 (ftp-data).
connect_from_port_20=YES
#
# If you want, you can arrange for uploaded anonymous files to be owned by
# a different user. Note! Using "root" for uploaded files is not
# recommended!
#chown_uploads=YES
#chown_username=whoever
#
# You may override where the log file goes if you like. The default is shown
# below.
#xferlog_file=/var/log/xferlog
#
# If you want, you can have your log file in standard ftpd xferlog format.
# Note that the default log file location is /var/log/xferlog in this case.
xferlog_std_format=YES
#
# You may change the default value for timing out an idle session.
#idle_session_timeout=600
#
# You may change the default value for timing out a data connection.
#data_connection_timeout=120
#
# It is recommended that you define on your system a unique user which the
# ftp server can use as a totally isolated and unprivileged user.
#nopriv_user=ftpsecure
#
# Enable this and the server will recognise asynchronous ABOR requests. Not
# recommended for security (the code is non-trivial). Not enabling it,
# however, may confuse older FTP clients.
#async_abor_enable=YES
#
# By default the server will pretend to allow ASCII mode but in fact ignore
# the request. Turn on the below options to have the server actually do ASCII
# mangling on files when in ASCII mode. The vsftpd.conf(5) man page explains
# the behaviour when these options are disabled.
# Beware that on some FTP servers, ASCII support allows a denial of service
# attack (DoS) via the command "SIZE /big/file" in ASCII mode. vsftpd
# predicted this attack and has always been safe, reporting the size of the
# raw file.
# ASCII mangling is a horrible feature of the protocol.
#开启
#ascii_upload_enable=YES
#开启
#ascii_download_enable=YES
#
# You may fully customise the login banner string:
#ftpd_banner=Welcome to blah FTP service.
#
# You may specify a file of disallowed anonymous e-mail addresses. Apparently
# useful for combatting certain DoS attacks.
#deny_email_enable=YES
# (default follows)
#banned_email_file=/etc/vsftpd/banned_emails
#
# You may specify an explicit list of local users to chroot() to their home
# directory. If chroot_local_user is YES, then this list becomes a list of
# users to NOT chroot().
# (Warning! chroot'ing can be very dangerous. If using chroot, make sure that
# the user does not have write access to the top level directory within the
# chroot)
#开启用限定用户在其主目录下,开启后需加入allow_writeable_chroot=YES
chroot_local_user=YES
#chroot_list_enable=YES
# (default follows)
#chroot_list_file=/etc/vsftpd/chroot_list
#
# You may activate the "-R" option to the builtin ls. This is disabled by
# default to avoid remote users being able to cause excessive I/O on large
# sites. However, some broken FTP clients such as "ncftp" and "mirror" assume
# the presence of the "-R" option, so there is a strong case for enabling it.
#ls_recurse_enable=YES
#
# When "listen" directive is enabled, vsftpd runs in standalone mode and
# listens on IPv4 sockets. This directive cannot be used in conjunction
# with the listen_ipv6 directive.
#listen=NO
listen=YES
#
# This directive enables listening on IPv6 sockets. By default, listening
# on the IPv6 "any" address (::) will accept connections from both IPv6
# and IPv4 clients. It is not necessary to listen on *both* IPv4 and IPv6
# sockets. If you want that (perhaps because you want to listen on specific
# addresses) then you must run two copies of vsftpd with two configuration
# files.
# Make sure, that one of the listen options is commented !!
#listen_ipv6=YES
listen_ipv6=NO pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
#设置访问目录
local_root=/home/ftpuser/
allow_writeable_chroot=YES #开启被动模式
pasv_enable=YES
#被动模式端口范围
pasv_min_port=6000
pasv_max_port=6010
#需要加入外部ip,否则被动模式会失败
pasv_address=39.96.38.179
pasv_addr_resolve=YES

接下来,开放阿里云服务器端口。

阿里云服务器+ftp文件操作+基于Centos7的vsftpd配置

20,21端口开放(22端口已默认开放)

阿里云服务器+ftp文件操作+基于Centos7的vsftpd配置

接下来,使用java代码进行文件操作。

FtpUtil.java工具类

package com.sun123.ftp.util;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply; /**
* ftp工具类
*/ public class FtpUtil { private final static Log logger = LogFactory.getLog(FtpUtil.class);
/** 本地字符编码 */
private static String LOCAL_CHARSET = "GBK"; // FTP协议里面,规定文件名编码为iso-8859-1
private static String SERVER_CHARSET = "ISO-8859-1"; /**
* 获取FTPClient对象
*
* @param ftpHost
* FTP主机服务器
*
* @param ftpPassword
* FTP 登录密码
*
* @param ftpUserName
* FTP登录用户名
*
* @param ftpPort
* FTP端口 默认为21
*
* @return
*/
public static FTPClient getFTPClient(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword) {
FTPClient ftpClient = null;
try {
ftpClient = new FTPClient();
ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
logger.info("未连接到FTP,用户名或密码错误。");
ftpClient.disconnect();
} else {
logger.info("FTP连接成功。");
}
} catch (SocketException e) {
e.printStackTrace();
logger.info("FTP的IP地址可能错误,请正确配置。");
} catch (IOException e) {
e.printStackTrace();
logger.info("FTP的端口错误,请正确配置。");
}
return ftpClient;
} /**
* 从FTP服务器下载文件
*
* @param ftpHost FTP IP地址
*
* @param ftpUserName FTP 用户名
*
* @param ftpPassword FTP用户名密码
*
* @param ftpPort FTP端口
*
* @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa
*
* @param localPath 下载到本地的位置 格式:H:/download
*
* @param fileName 文件名称
*/
public static void downloadFtpFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort,
String ftpPath, String localPath, String fileName) { FTPClient ftpClient = null; try {
ftpClient = getFTPClient(ftpHost, ftpPort, ftpUserName, ftpPassword);
// 设置上传文件的类型为二进制类型
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
LOCAL_CHARSET = "UTF-8";
}
ftpClient.setControlEncoding(LOCAL_CHARSET);
ftpClient.enterLocalPassiveMode();// 设置被动模式
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 设置传输的模式
// 上传文件
//对中文文件名进行转码,否则中文名称的文件下载失败
String fileNameTemp = new String(fileName.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
ftpClient.changeWorkingDirectory(ftpPath); InputStream retrieveFileStream = ftpClient.retrieveFileStream(fileNameTemp); // 第一种方式下载文件(推荐)
/* File localFile = new File(localPath + File.separatorChar + fileName);
OutputStream os = new FileOutputStream(localFile);
ftpClient.retrieveFile(fileName, os); os.close();*/ // 第二种方式下载:将输入流转成字节,再生成文件,这种方式方便将字节数组直接返回给前台jsp页面
byte[] input2byte = input2byte(retrieveFileStream);
byte2File(input2byte, localPath, fileName); if(null != retrieveFileStream){
retrieveFileStream.close();
}
} catch (FileNotFoundException e) {
logger.error("没有找到" + ftpPath + "文件");
e.printStackTrace();
} catch (SocketException e) {
logger.error("连接FTP失败.");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
logger.error("文件读取错误。");
e.printStackTrace();
} finally { if (ftpClient.isConnected()) {
try {
//退出登录
ftpClient.logout();
//关闭连接
ftpClient.disconnect();
} catch (IOException e) {
}
}
}
} /**
* Description: 向FTP服务器上传文件
*
* @param host
* FTP服务器hostname
* @param port
* FTP服务器端口
* @param username
* FTP登录账号
* @param password
* FTP登录密码
* @param basePath
* FTP服务器基础目录
* @param filePath
* FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
* @param filename
* 上传到FTP服务器上的文件名
* @param input
* 输入流
* @return 成功返回true,否则返回false
*/
/*String host, int port, String username, String password, String remotePath,
String fileName, String localPath*/
public static boolean uploadFile(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword,
String basePath, String filePath, String filename, InputStream input) {
boolean result = false;
FTPClient ftpClient = null;
try {
int reply;
ftpClient = getFTPClient(ftpHost, ftpPort, ftpUserName, ftpPassword);
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
return result;
}
// 切换到上传目录
if (!ftpClient.changeWorkingDirectory(basePath + filePath)) {
// 如果目录不存在创建目录
String[] dirs = filePath.split("/");
String tempPath = basePath;
for (String dir : dirs) {
if (null == dir || "".equals(dir))
continue;
tempPath += "/" + dir;
if (!ftpClient.changeWorkingDirectory(tempPath)) {
if (!ftpClient.makeDirectory(tempPath)) {
return result;
} else {
ftpClient.changeWorkingDirectory(tempPath);
}
}
}
}
// 设置上传文件的类型为二进制类型
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
LOCAL_CHARSET = "UTF-8";
}
ftpClient.setControlEncoding(LOCAL_CHARSET);
ftpClient.enterLocalPassiveMode();// 设置被动模式
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 设置传输的模式
// 上传文件
filename = new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
if (!ftpClient.storeFile(filename, input)) {
return result;
} if(null != input){
input.close();
} result = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
//退出登录
ftpClient.logout();
//关闭连接
ftpClient.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
} /**
* 删除文件
*
* @param hostname
* FTP服务器地址
* @param port
* FTP服务器端口号
* @param username
* FTP登录帐号
* @param password
* FTP登录密码
* @param pathname
* FTP服务器保存目录
* @param filename
* 要删除的文件名称
* @return
*/
public static boolean deleteFile(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword, String pathname,
String filename) {
boolean flag = false;
FTPClient ftpClient = new FTPClient();
try {
ftpClient = getFTPClient(ftpHost, ftpPort, ftpUserName, ftpPassword);
// 验证FTP服务器是否登录成功
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
return flag;
}
// 切换FTP目录
ftpClient.changeWorkingDirectory(pathname);
// 设置上传文件的类型为二进制类型
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
LOCAL_CHARSET = "UTF-8";
}
ftpClient.setControlEncoding(LOCAL_CHARSET);
ftpClient.enterLocalPassiveMode();// 设置被动模式
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 设置传输的模式
//对中文名称进行转码
filename = new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
ftpClient.dele(filename);
flag = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
//退出登录
ftpClient.logout();
//关闭连接
ftpClient.disconnect();
} catch (IOException e) {
}
}
}
return flag;
} // 将字节数组转换为输入流
public static final InputStream byte2Input(byte[] buf) {
return new ByteArrayInputStream(buf);
} // 将输入流转为byte[]
public static final byte[] input2byte(InputStream inStream) throws IOException {
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while ((rc = inStream.read(buff, 0, 100)) > 0) {
swapStream.write(buff, 0, rc);
}
byte[] in2b = swapStream.toByteArray();
return in2b;
} // 将byte[]转为文件
public static void byte2File(byte[] buf, String filePath, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
try {
File dir = new File(filePath);
if (!dir.exists() && dir.isDirectory()) {
dir.mkdirs();
}
file = new File(filePath + File.separator + fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(buf);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

FtpTest.java测试类:

package com.sun123.ftp.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException; import org.joda.time.DateTime; import com.sun123.ftp.util.FtpUtil; public class FtpTest {
public static void main(String[] args) throws FileNotFoundException {
//ftp服务器IP地址
String ftpHost = "12.34.56.789"; //仅供参考
//ftp服务器端口
int ftpPort = 21;
//ftp服务器用户名
String ftpUserName = "ftp";
//ftp服务器密码
String ftpPassword = "123456";
//ftp服务器路径
//必须有"/"
String ftpPath = "/tasksystem/images/stu/headportrait"; //本地路径
String localPath = "O://";
//文件名
String fileName = "1.jpg"; //下载
//将ftp根目录下的文件下载至E盘
// FtpUtil.downloadFtpFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, localPath, fileName); String imagePath = new DateTime().toString("/yyyy/MM/dd");//上传
//将E盘的文件上传至ftp根目录
FileInputStream in=new FileInputStream(new File(localPath + fileName));
FtpUtil.uploadFile(ftpHost, ftpPort, ftpUserName, ftpPassword, ftpPath , imagePath, fileName, in); //删除
//删除ftp根目录下的文件
//FtpUtil.deleteFile(ftpHost, ftpPort, ftpUserName, ftpPassword, ftpPath + imagePath, "1111556507044860411.jpg"); }
}

经测试,文件上传和删除均有效。

说明:joda-time时间插件很好用

点击进行源码下载

参考:https://blog.csdn.net/ljj2312/article/details/78968037

上一篇:Django的分页和中间件


下一篇:51 Nod 1091 线段的重叠