ftp文件传输

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

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值