设为首页 收藏本站
查看: 757|回复: 0

[经验分享] Apache common FTP-J2EE

[复制链接]

尚未签到

发表于 2018-11-28 09:12:00 | 显示全部楼层 |阅读模式
  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>  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 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 retList = new ArrayList();
  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  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>  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>  /**
  * @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 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);
  }
  }
  }


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-640547-1-1.html 上篇帖子: Apache Threatens to Leave JCP-Sky的博客 下篇帖子: apache编译优化
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表