1. 程式人生 > >CentOS6.5下搭建FTP伺服器 + Java上傳檔案

CentOS6.5下搭建FTP伺服器 + Java上傳檔案

/**
 * @Type ftpClientFileManager.java
 * @Desc 
 * @author 123
 * @date 2017年3月31日 下午2:50:58
 * @version 
 */
@Service
public class FTPFileManager {

    private static final Logger logger = LoggerFactory.getLogger(FTPFileManager.class);

    private FTPClient ftpClient = new FTPClient();

    /** 路徑分隔符 */
    private static final String SEPARATOR = "/";

    /** FTP訪問路徑字首 */
    private static final String FTP_PREFIX = "ftp://";

    @Autowired
    private FTPConfig config;

    /**
     * @Title: upload 
     *
     * @Description: 檔案上傳
     *
     * @param uploadFile
     *          MultipartFile
     * @return
     *          返回儲存路徑 + 檔名
     * @throws Exception 
     *
     */
    public String upload(MultipartFile uploadFile) throws Exception {

        ftpClient = new FTPClient();
        ftpClient.connect(config.getfTPhost(), config.getFtpPort());

        ftpClient.login(config.getFtpUserName(), config.getFtpUserPasswd());
        //設定ftp位元組流
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        int reply;
        reply = ftpClient.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftpClient.disconnect();
            return null;
        }
        ftpClient.enterLocalPassiveMode();
        String basePath = config.getRemoteFileAddr();
        ftpClient.changeWorkingDirectory(basePath);

        //為當天日期檔案建立追加目錄
        Date today = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        String appendFile = sdf.format(today);
        //切換到上傳目錄
        if (!ftpClient.changeWorkingDirectory(basePath + appendFile)) {
            //如果目錄不存在建立目錄
            String[] dirs = appendFile.split(SEPARATOR);
            String tempTargetPath = basePath;
            for (String dir : dirs) {
                if (null == dir || "".equals(dir))
                    continue;
                tempTargetPath += SEPARATOR + dir;
                if (!ftpClient.changeWorkingDirectory(tempTargetPath)) {
                    if (!ftpClient.makeDirectory(tempTargetPath)) {
                        logger.error("ftp檔案目錄建立失敗!");
                        return null;
                    } else {
                        ftpClient.changeWorkingDirectory(tempTargetPath);
                    }
                }
            }
        }

        String fileName = new String(uploadFile.getOriginalFilename().getBytes("utf-8"),
                "iso-8859-1");
        /**
         * 避免檔案過多後出現重名,設定30位隨機數為檔名稱
         */
        // 獲取副檔名 形如: .txt
        String fileExt = fileName.substring(fileName.lastIndexOf("."));
        String newFileName = RandomUtils.randomAlphanumericStrictly(30) + fileExt;

        InputStream is = uploadFile.getInputStream();
        if (!ftpClient.storeFile(newFileName, is)) {
            logger.error("檔案{}儲存過程出錯", fileName);
            return null;
        }
        is.close();
        ftpClient.disconnect();
        /* String finalFile = basePath + SEPARATOR + appendFile + SEPARATOR + fileName;*/
        //直接儲存為匿名使用者可直接訪問下載的地址
        String finalFile = FTP_PREFIX + config.getFtpNetAdd() + ":" + config.getFtpNetPort()
                + SEPARATOR + "pub" + SEPARATOR + appendFile + SEPARATOR + newFileName;
        logger.info("檔案上傳FTP伺服器成功, 訪問檔案路徑為 : " + finalFile);
        return finalFile;
    }

    /** 
     * 從FTP伺服器上下載檔案 
     * @param remote 遠端檔案路徑 
     * @param local 本地檔案路徑 
     * @return 是否成功 
     * @throws Exception 
     */
    public boolean download(String remote, String local) throws Exception {
        ftpClient = new FTPClient();
        ftpClient.connect(config.getfTPhost(), config.getFtpPort());
        ftpClient.login(config.getFtpUserName(), config.getFtpUserPasswd());
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        int reply;
        reply = ftpClient.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftpClient.disconnect();
            return false;
        }

        ftpClient.enterLocalPassiveMode();
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        boolean result;
        File f = new File(local);
        FTPFile[] files = ftpClient.listFiles(remote);
        if (files.length != 1) {
            System.out.println("遠端檔案不唯一");
            ftpClient.disconnect();
            return false;
        }
        long lRemoteSize = files[0].getSize();
        if (f.exists()) {
            OutputStream out = new FileOutputStream(f, true);
            System.out.println("本地檔案大小為:" + f.length());
            if (f.length() >= lRemoteSize) {
                logger.error("本地檔案大小大於遠端檔案大小,下載中止");
                out.close();
                ftpClient.disconnect();
                return false;
            }
            ftpClient.setRestartOffset(f.length());
            result = ftpClient.retrieveFile(remote, out);
            out.close();
        } else {
            OutputStream out = new FileOutputStream(f);
            result = ftpClient.retrieveFile(remote, out);
            out.close();
        }
        ftpClient.disconnect();
        return result;
    }

}

/**
 * Revision history
 * -------------------------------------------------------------------------
 * 
 * Date Author Note
 * -------------------------------------------------------------------------
 * 2017年3月31日 123 creat
 */
此時,使用者可以通過公網對映的IP進行訪問, 類似 ftp://218.205.115.XXXX:2121/pub/2017/04/06/4cn91c2dRffmQ8diQ4mvDRo5m2lWtr.txt
由於專案中沒使用到檔案下載,我只在本地進行了簡單的下載centOS中FTP檔案測試.