阿里雲服務器+ftp文件操做+基於Centos7的vsftpd配置

路徑問題:必定要注意此位置是否須要加入"/"java

文件上傳方式:被動模式apache

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

接下來,開放阿里雲服務器端口。服務器

20,21端口開放(22端口已默認開放)session

接下來,使用java代碼進行文件操做。app

FtpUtil.java工具類socket

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測試類:jsp

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");
        
        
    }
}  

經測試,文件上傳和刪除均有效。async

說明:joda-time時間插件很好用tcp

點擊進行源碼下載

 

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

相關文章
相關標籤/搜索