2025-02-10

  import java.io.File;

    import java.io.FileOutputStream;

    import java.io.IOException;

    import java.io.InputStream;

    import java.io.OutputStream;

    import java.io.RandomAccessFile;

    import java.net.SocketException;

    import java.util.ArrayList;

    import java.util.List;

    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.FTPFile;

    import org.apache.commons.net.ftp.FTPReply;

    

    /**

     * FTP工具類

     * @author WangXianfeng 1:16:50 PM Jul 16, 2011

    

     */

    

    public class FtpUtil {

           private FTPClient ftpClient;

           private static Log log = LogFactory.getLog(FtpUtil.class);

           /**

    

            * 根路徑為"/",如果需要鏈接服務器之後跳轉到路徑,則在path中定義

    

            * @param ftpConfig

    

            * @throws SocketException

    

            * @throws IOException

    

            */

    

           public boolean connectServer(FtpConfig ftpConfig) throws SocketException,

                         IOException {

                  String server = ftpConfig.getServer();

                  int port = ftpConfig.getPort();

                  String user = ftpConfig.getUsername();

                  String password = ftpConfig.getPassword();

                  String path = ftpConfig.getPath();

                  return connectServer(server, port, user, password, path);

           }

    

           /**

    

            * 連接ftp服務器

    

            * @param server 服務器ip

    

            * @param port 端口,通常為21

    

            * @param user 用戶名

    

            * @param password 密碼

    

            * @param path 進入服務器之後的默認路徑

    

            * @return 連接成功返回true,否則返回false

    

            * @throws SocketException

    

            * @throws IOException

    

            */

    

           public boolean connectServer(String server, int port, String user,

                         String password, String path) throws SocketException, IOException {

                  ftpClient = new FTPClient();

                  ftpClient.connect(server, port);

                  ftpClient.setControlEncoding("GBK");

                  log.info("Connected to " + server + ".");

                  log.info("FTP server reply code:" + ftpClient.getReplyCode());

                  if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {

                         if (ftpClient.login(user, password)) {

                                // Path is the sub-path of the FTP path

                                if (path.length() != 0) {

                                       ftpClient.changeWorkingDirectory(path);

                                }

                                return true;

    

                         }

    

                  }

    

                  disconnect();

    

                  return false;

    

           }

    

           /**

    

            * 斷開與遠程服務器的連接

    

            * @throws IOException

    

            */

    

           public void disconnect() throws IOException {

    

                  if (ftpClient.isConnected()) {

    

                         ftpClient.disconnect();

    

                  }

    

           }

    

          

    

           /**

    

            * 從FTP服務器上下載文件,支持斷點續傳,下載百分比匯報

    

            * @param remote 遠程文件路徑及名稱

    

            * @param local 本地文件完整絕對路徑

    

            * @return 下載的狀態

    

            * @throws IOException

    

            */

    

           public DownloadStatus download(String remote, String local)

    

                         throws IOException {

    

                  // 設置被動模式

    

                  ftpClient.enterLocalPassiveMode();

    

                  // 設置以二進制方式傳輸

    

                  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

    

                  DownloadStatus result;

    

      

    

                  // 檢查遠程文件是否存在

    

                  FTPFile[] files = ftpClient.listFiles(new String(

    

                                remote.getBytes("GBK"), "iso-8859-1"));

    

                  if (files.length != 1) {

    

                         log.info("遠程文件不存在");

    

                         return DownloadStatus.RemoteFileNotExist;

                  }

                  long lRemoteSize = files[0].getSize();

                  File f = new File(local);

                  // 本地存在文件,進行斷點下載

                  if (f.exists()) {

                         long localSize = f.length();

                         // 判斷本地文件大小是否大於遠程文件大小

                         if (localSize >= lRemoteSize) {

                                log.info("本地文件大於遠程文件,下載中止");

                                return DownloadStatus.LocalFileBiggerThanRemoteFile;

                         }

    

                         // 進行斷點續傳,並記錄狀態

    

                         FileOutputStream out = new FileOutputStream(f, true);

    

                         ftpClient.setRestartOffset(localSize);

    

                         InputStream in = ftpClient.retrieveFileStream(new String(remote

    

                                       .getBytes("GBK"), "iso-8859-1"));

    

                         byte[] bytes = new byte[1024];

    

                         long step = lRemoteSize / 100;

    

                         step = step==0?1:step;//文件過小,step可能為0

    

                         long process = localSize / step;

    

                         int c;

    

                         while ((c = in.read(bytes)) != -1) {

    

                                out.write(bytes, 0, c);

    

                                localSize += c;

    

                                long nowProcess = localSize / step;

    

                                if (nowProcess > process) {

    

                                       process = nowProcess;

    

                                       if (process % 10 == 0){

    

                                              log.info("下載進度:" + process);

    

                                       }

    

                                }

    

                         }

    

                         in.close();

    

                         out.close();

    

                         boolean isDo = ftpClient.completePendingCommand();

    

                         if (isDo) {

    

                                result = DownloadStatus.DownloadFromBreakSuccess;

    

                         } else {

    

                                result = DownloadStatus.DownloadFromBreakFailed;

    

                         }

    

                  } else {

    

                         OutputStream out = new FileOutputStream(f);

    

                         InputStream in = ftpClient.retrieveFileStream(new String(remote

    

                                       .getBytes("GBK"), "iso-8859-1"));

    

                         byte[] bytes = new byte[1024];

    

                         long step = lRemoteSize / 100;

    

                         step = step==0?1:step;//文件過小,step可能為0

    

                         long process = 0;

    

                         long localSize = 0L;

    

                         int c;

    

                         while ((c = in.read(bytes)) != -1) {

    

                                out.write(bytes, 0, c);

    

                                localSize += c;

    

                                long nowProcess = localSize / step;

    

                                if (nowProcess > process) {

    

                                       process = nowProcess;

    

                                       if (process % 10 == 0){

    

                                              log.info("下載進度:" + process);

    

                                       }

    

                                }

    

                         }

    

                         in.close();

    

                         out.close();

    

                         boolean upNewStatus = ftpClient.completePendingCommand();

    

                         if (upNewStatus) {

    

                                result = DownloadStatus.DownloadNewSuccess;

    

                         } else {

    

                                result = DownloadStatus.DownloadNewFailed;

    

                         }

    

                  }

    

                  return result;

    

           }

    

     

    

           public boolean changeDirectory(String path) throws IOException {

    

                  return ftpClient.changeWorkingDirectory(path);

    

           }

    

     

    

           public boolean createDirectory(String pathName) throws IOException {

    

                  return ftpClient.makeDirectory(pathName);

    

           }

    

     

    

           public boolean removeDirectory(String path) throws IOException {

                  return ftpClient.removeDirectory(path);

           }

           public boolean removeDirectory(String path, boolean isAll)

                         throws IOException {

                  if (!isAll) {

                         return removeDirectory(path);

                  }

                  FTPFile[] ftpFileArr = ftpClient.listFiles(path);

                  if (ftpFileArr == null || ftpFileArr.length == 0) {

                         return removeDirectory(path);

                  }

    

                  //  

    

                  for (FTPFile ftpFile : ftpFileArr) {

                         String name = ftpFile.getName();

                         if (ftpFile.isDirectory()) {

                                log.info("* [sD]Delete subPath [" + path + "/" + name + "]");

                                if (!ftpFile.getName().equals(".")

                                              && (!ftpFile.getName().equals(".."))) {

                                       removeDirectory(path + "/" + name, true);

                                }

    

                         } else if (ftpFile.isFile()) {

                                log.info("* [sF]Delete file [" + path + "/" + name + "]");

                                deleteFile(path + "/" + name);

                         } else if (ftpFile.isSymbolicLink()) {

                         } else if (ftpFile.isUnknown()) {

                         }

                  }

                  return ftpClient.removeDirectory(path);

    

           }

    

     

    

           /**

    

            * 查看目錄是否存在

    

            * @param path

    

            * @return

    

            * @throws IOException

    

            */

    

           public boolean isDirectoryExists(String path) throws IOException {

    

                  boolean flag = false;

    

                  FTPFile[] ftpFileArr = ftpClient.listFiles(path);

    

                  for (FTPFile ftpFile : ftpFileArr) {

    

                         if (ftpFile.isDirectory()

    

                                       && ftpFile.getName().equalsIgnoreCase(path)) {

    

                                flag = true;

    

                                break;

    

                         }

    

                  }

    

                  return flag;

    

           }

    

     

    

           /**

    

            * 得到某個目錄下的文件名列表

    

            * @param path

    

            * @return

    

            * @throws IOException

    

            */

    

           public List<String> getFileList(String path) throws IOException {

    

                  // listFiles return contains directory and file, it's FTPFile instance

    

                  // listNames() contains directory, so using following to filer

    

                  // directory.

    

                  // String[] fileNameArr = ftpClient.listNames(path);

    

                  FTPFile[] ftpFiles = ftpClient.listFiles(path);

    

     

    

                  List<String> retList = new ArrayList<String>();

    

                  if (ftpFiles == null || ftpFiles.length == 0) {

    

                         return retList;

    

                  }

    

                  for (FTPFile ftpFile : ftpFiles) {

    

                         if (ftpFile.isFile()) {

    

                                retList.add(ftpFile.getName());

    

                         }

    

                  }

    

                  return retList;

    

           }

    

           

    

           public boolean deleteFile(String pathName) throws IOException {

    

                  return ftpClient.deleteFile(pathName);

    

           }

    

     

    

           /**

    

            * 上傳文件到FTP服務器,支持斷點續傳

    

            * @param local 本地文件名稱,絕對路徑

    

            * @param remote 遠程文件路徑,按照Linux上的路徑指定方式,支持多級目錄嵌套,支持遞歸創建不存在的目錄結構

    

            * @return 上傳結果

    

            * @throws IOException

    

            */

    

           public UploadStatus upload(String local, String remote) throws IOException {

    

                  // 設置PassiveMode傳輸

    

                  ftpClient.enterLocalPassiveMode();

    

                  // 設置以二進制流的方式傳輸

    

                  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

    

                  ftpClient.setControlEncoding("GBK");

    

                  UploadStatus result;

    

                  // 對遠程目錄的處理

    

                  String remoteFileName = remote;

                  if (remote.contains("/")) {

                         remoteFileName = remote.substring(remote.lastIndexOf("/") + 1);

                         // 創建服務器遠程目錄結構,創建失敗直接返回

                         if (createDirecroty(remote, ftpClient) == UploadStatus.CreateDirectoryFail) {

                                return UploadStatus.CreateDirectoryFail;

                         }

                  }

    

     

    

                  // 檢查遠程是否存在文件

    

                  FTPFile[] files = ftpClient.listFiles(new String(remoteFileName

    

                                .getBytes("GBK"), "iso-8859-1"));

    

                  if (files.length == 1) {

    

                         long remoteSize = files[0].getSize();

    

                         File f = new File(local);

    

                         long localSize = f.length();

    

                         if (remoteSize == localSize) { // 文件存在

    

                                return UploadStatus.FileExits;

    

                         } else if (remoteSize > localSize) {

    

                                return UploadStatus.RemoteFileBiggerThanLocalFile;

    

                         }

   

                         // 嘗試移動文件內讀取指針,實現斷點續傳

                         result = uploadFile(remoteFileName, f, ftpClient, remoteSize);

                         // 如果斷點續傳沒有成功,則刪除服務器上文件,重新上傳

                         if (result == UploadStatus.UploadFromBreakFailed) {

                                if (!ftpClient.deleteFile(remoteFileName)) {

                                       return UploadStatus.DeleteRemoteFaild;

                                }

                                result = uploadFile(remoteFileName, f, ftpClient, 0);

                         }

    

                  } else {

    

                         result = uploadFile(remoteFileName, new File(local), ftpClient, 0);

                  }

                  return result;

           }

    

          

    

           /**

    

            * 遞歸創建遠程服務器目錄

    

            * @param remote 遠程服務器文件絕對路徑

    

            * @param ftpClient FTPClient對象

    

            * @return 目錄創建是否成功

    

            * @throws IOException

    

            */

    

           public UploadStatus createDirecroty(String remote, FTPClient ftpClient)

    

                         throws IOException {

    

                  UploadStatus status = UploadStatus.CreateDirectorySuccess;

    

                  String directory = remote.substring(0, remote.lastIndexOf("/") + 1);

    

                  if (!directory.equalsIgnoreCase("/")

    

                                && !ftpClient.changeWorkingDirectory(new String(directory

    

                                              .getBytes("GBK"), "iso-8859-1"))) {

    

                         // 如果遠程目錄不存在,則遞歸創建遠程服務器目錄

    

                         int start = 0;

    

                         int end = 0;

    

                         if (directory.startsWith("/")) {

    

                                start = 1;

    

                         } else {

    

                                start = 0;

    

                         }

    

                         end = directory.indexOf("/", start);

    

                         while (true) {

    

                                String subDirectory = new String(remote.substring(start, end)

    

                                              .getBytes("GBK"), "iso-8859-1");

                                if (!ftpClient.changeWorkingDirectory(subDirectory)) {

                                       if (ftpClient.makeDirectory(subDirectory)) {

                                              ftpClient.changeWorkingDirectory(subDirectory);

                                       } else {

                                              log.info("創建目錄失敗");

                                              return UploadStatus.CreateDirectoryFail;

                                       }

                                }

                                start = end + 1;

                                end = directory.indexOf("/", start);

                                // 檢查所有目錄是否創建完畢

                                if (end <= start) {

                                       break;

                                }

                         }

                  }

                  return status;

           }

    

          

    

           /**

    

            * 上傳文件到服務器,新上傳和斷點續傳

    

            * @param remoteFile 遠程文件名,在上傳之前已經將服務器工作目錄做瞭改變

    

            * @param localFile 本地文件File句柄,絕對路徑

    

            * @param processStep 需要顯示的處理進度步進值

    

            * @param ftpClient FTPClient引用

    

            * @return

    

            * @throws IOException

    

            */

    

           public UploadStatus uploadFile(String remoteFile, File localFile,

    

                         FTPClient ftpClient, long remoteSize) throws IOException {

    

                  UploadStatus status;

    

                  // 顯示進度的上傳

    

                  System.out.println("localFile.length():"+localFile.length());

    

                  long step = localFile.length() / 100;

    

                  step = step==0?1:step;//文件過小,step可能為0

    

                  long process = 0;

    

                  long localreadbytes = 0L;

    

                  RandomAccessFile raf = new RandomAccessFile(localFile, "r");

    

                  OutputStream out = ftpClient.appendFileStream(new String(remoteFile

    

                                .getBytes("GBK"), "iso-8859-1"));

    

                  // 斷點續傳

    

                  if (remoteSize > 0) {

    

                         ftpClient.setRestartOffset(remoteSize);

    

                         process = remoteSize / step;

    

                         raf.seek(remoteSize);

    

                         localreadbytes = remoteSize;

    

                  }

    

                  byte[] bytes = new byte[1024];

    

                  int c;

    

                  while ((c = raf.read(bytes)) != -1) {

    

                         out.write(bytes, 0, c);

    

                         localreadbytes += c;

    

                         if (localreadbytes / step != process) {

    

                                process = localreadbytes / step;

    

                                if (process % 10 == 0){

    

                                       log.info("上傳進度:" + process);

    

                                }

    

                         }

    

                  }

    

                  out.flush();

    

                  raf.close();

    

                  out.close();

    

                  boolean result = ftpClient.completePendingCommand();

    

                  if (remoteSize > 0) {

    

                         status = result ? UploadStatus.UploadFromBreakSuccess

    

                                       : UploadStatus.UploadFromBreakFailed;

    

                  } else {

    

                         status = result ? UploadStatus.UploadNewFileSuccess

    

                                       : UploadStatus.UploadNewFileFailed;

                  }

                  return status;

           }

    

           public InputStream downFile(String sourceFileName) throws IOException {

                  return ftpClient.retrieveFileStream(sourceFileName);

           }

    

           public enum UploadStatus {

                  CreateDirectoryFail, // 遠程服務器相應目錄創建失敗

                  CreateDirectorySuccess, // 遠程服務器闖將目錄成功

                  UploadNewFileSuccess, // 上傳新文件成功

                  UploadNewFileFailed, // 上傳新文件失敗

                  FileExits, // 文件已經存在

                  RemoteFileBiggerThanLocalFile, // 遠程文件大於本地文件

                  UploadFromBreakSuccess, // 斷點續傳成功

                  UploadFromBreakFailed, // 斷點續傳失敗

                  DeleteRemoteFaild; // 刪除遠程文件失敗

           }

    

           public enum DownloadStatus {

                  RemoteFileNotExist, // 遠程文件不存在

                  DownloadNewSuccess, // 下載文件成功

                  DownloadNewFailed, // 下載文件失敗

                  LocalFileBiggerThanRemoteFile, // 本地文件大於遠程文件

                  DownloadFromBreakSuccess, // 斷點續傳成功

                  DownloadFromBreakFailed; // 斷點續傳失敗

           }

    }

    

    FtpConfig類:

    /**

     *

     */

    package com.pccw.portlet.publictools;

    

    /**

     * FTP配置類

     * @author WangXianfeng 1:18:45 PM Jul 16, 2011

     */

    public class FtpConfig {

        private String server;

        private int port;

        private String username;

        private String password;

        private String path;

        gets  。。sets。。

    }

    

    測試類:

    import java.util.List;

    

    import com.pccw.portlet.publictools.FtpConfig;

    import com.pccw.portlet.publictools.FtpUtil;

    

    /**

     *

     * @author WangXianfeng 1:20:45 PM Jul 16, 2011

     */

    public class HelloWorld {

        /**

         * @param args

         */

        public static void main(String[] args) throws Exception {

            FtpConfig config = new FtpConfig();

            config.setServer("192.168.0.199");

            config.setPort(21);

            config.setUsername("wxf");

            config.setPassword("wxf");

            config.setPath("bankafile");

            FtpUtil ftp = new FtpUtil();

            ftp.connectServer(config);

            String localFile = "c:\\Seagull.rar";

            ftp.upload(localFile, "sea.rar");

            List<String> files = ftp.getFileList("");

            //ftp.changeDirectory("bankafile");

           

            for(String file:files){

                System.out.println(file);

                String local = "D:\\ct\\199\\temp\\" + file;

                ftp.download(file, local);

            }

        }

    }

作者“ERDP技術架構”

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *