需求:

在前面一篇文章中http://supercharles888.blog.51cto.com/609344/980322,我们已经介绍了如何创建一个到远程服务器的连接,那么这里我们就介绍如何通过这个连接来从远程服务器删除单个目录。

 

实现:

同样,所有的操作都是在ch.ethz.ssh2包中,所以我们必须在maven dependency中声明对相应artifact的依赖.

  1. <!-- charles:this artifact is used for implementing the scp feature --> 
  2.  
  3.                 <dependency> 
  4.  
  5.                          <groupId>ch.ethz.ganymed</groupId> 
  6.  
  7.                          <artifactId>ganymed-ssh2</artifactId> 
  8.  
  9.                          <version>build210</version> 
  10.  
  11.                 </dependency> 

 

从远程服务器指定目录删除单个目录的实现,贴上代码:

  1. /** 
  2.  
  3.          * This method can do the remote delete a folder feature from the web server 
  4.  
  5.          * @param folderPath the folder path which relative to the "htdocs" folder of the web server directory 
  6.  
  7.          * @throws Exception 
  8.  
  9.           */ 
  10.  
  11.          public void deleteFolderFromWebServer(String folderPath) throws Exception { 
  12.  
  13.   
  14.  
  15.                  // check the folderPath shouldn't be null 
  16.  
  17.                  if ((folderPath == null) || (folderPath.trim().equals(EMPTY_STRING))) { 
  18.  
  19.                           if (logger.isErrorEnabled()) { 
  20.  
  21.                                             logger.error("the folder path that we want to delete from remote web server shouldn't be null"); 
  22.  
  23.                           } 
  24.  
  25.                           throw new ParameterNullException( 
  26.  
  27.                                    "the folder path that we want to delete from remote web server shouldn't be null"); 
  28.  
  29.                  } 
  30.  
  31.   
  32.  
  33.                  if (logger.isDebugEnabled()) { 
  34.  
  35.                           logger.debug("Begin to delete the folder " + folderPath 
  36.  
  37.                                                              + " from WebServer: " + connFactory.getWebServerName()); 
  38.  
  39.                  } 
  40.  
  41.   
  42.  
  43.                  // get the connection object 
  44.  
  45.                  Connection conn = connFactory.getServerMachineConnection(); 
  46.  
  47.   
  48.  
  49.                  if (conn == null) { 
  50.  
  51.                           if (logger.isErrorEnabled()) { 
  52.  
  53.                                             logger.error("Failed to establish the valid connection with web server " 
  54.  
  55.                                                              + connFactory.getWebServerName()); 
  56.  
  57.   
  58.  
  59.                           } 
  60.  
  61.   
  62.  
  63.                           throw new DeleteFromWebServerException( 
  64.  
  65.                                             "Failed to establish the valid connection with web server "+ connFactory.getWebServerName()); 
  66.  
  67.                  } 
  68.  
  69.   
  70.  
  71.   
  72.  
  73.                  SFTPv3Client client = new SFTPv3Client(conn); 
  74.  
  75.   
  76.  
  77.                  // use the sftp client to remote delete the folder 
  78.  
  79.   
  80.  
  81.                  try { 
  82.  
  83.   
  84.  
  85.   
  86.  
  87.                                    sftpDeleteFolderRecursive(client,webServerRoot + FORWARD_SLASH +folderPath); 
  88.  
  89.   
  90.  
  91.                                    } catch (IOException ex) { 
  92.  
  93.   
  94.  
  95.                                             if (logger.isErrorEnabled()) { 
  96.  
  97.                                                              logger.error("IOException occured during remote delete folder from "+connFactory.getWebServerName()); 
  98.  
  99.   
  100.  
  101.                                             } 
  102.  
  103.   
  104.  
  105.                                             conn.close(); 
  106.  
  107.                                            throw new DeleteFromWebServerException( 
  108.  
  109.                                                                       "IOException occured during remote delete folder from "+connFactory.getWebServerName(),ex); 
  110.  
  111.                                    } 
  112.  
  113.   
  114.  
  115.   
  116.  
  117.                                    if (logger.isDebugEnabled()) { 
  118.  
  119.                                                              logger.debug("remote delete folder from web server: " + webServerRoot + " successful"); 
  120.  
  121.                                    } 
  122.  
  123.   
  124.  
  125.                                    // close the connection to web server 
  126.  
  127.                                    conn.close(); 
  128.  
  129.          } 
  130.  
  131.   
  132.  
  133.   
  134.  
  135.          private List<SFTPv3DirectoryEntry> sftpGetFileList(SFTPv3Client client, String directory) throws Exception 
  136.  
  137.          { 
  138.  
  139.                  List<SFTPv3DirectoryEntry> fileEntries = new ArrayList<SFTPv3DirectoryEntry>(); 
  140.  
  141.                  Vector<?> files = client.ls(directory); 
  142.  
  143.   
  144.  
  145.                  for (Iterator<?> elements = files.iterator() ; elements.hasNext() ; ) { 
  146.  
  147.                           SFTPv3DirectoryEntry file = (SFTPv3DirectoryEntry) elements.next(); 
  148.  
  149.                           String fileName = file.filename.trim(); 
  150.  
  151.   
  152.  
  153.                           if(!fileName.equals(".") && !fileName.equals("..")) 
  154.  
  155.                                    fileEntries.add(file); 
  156.  
  157.                  } 
  158.  
  159.   
  160.  
  161.                  return fileEntries; 
  162.  
  163.          } 
  164.  
  165.   
  166.  
  167.   
  168.  
  169.          /** 
  170.  
  171.          * This method can do the sftp delete a folder recursively feature from the web server 
  172.  
  173.          * @param folderPath the folder path which relative to the "htdocs" folder of the web server directory 
  174.  
  175.          * @throws Exception 
  176.  
  177.           */ 
  178.  
  179.          private void sftpDeleteFolderRecursive(SFTPv3Client client,String folderPath) throws Exception { 
  180.  
  181.   
  182.  
  183.                  List<SFTPv3DirectoryEntry> files =  sftpGetFileList(client,folderPath); 
  184.  
  185.   
  186.  
  187.                  for(SFTPv3DirectoryEntry file : files) 
  188.  
  189.                  { 
  190.  
  191.                           String fileName = file.filename; 
  192.  
  193.                          if(".".equals(fileName.trim()) == false && "..".equals(fileName.trim()) == false
  194.  
  195.                           { 
  196.  
  197.                                    //if the file object is a directory,then recursively invokes this method 
  198.  
  199.                                    if (file.attributes.isDirectory()) 
  200.  
  201.                                    { 
  202.  
  203.                                             sftpDeleteFolderRecursive(client, folderPath + "/" + fileName); 
  204.  
  205.                                    } else 
  206.  
  207.                                    //if the file object is a file ,then just client.rm to sftp delete this file 
  208.  
  209.                                    { 
  210.  
  211.                                             client.rm(folderPath + "/" + fileName); 
  212.  
  213.                                    } 
  214.  
  215.                           } 
  216.  
  217.                  } 
  218.  
  219.                  client.rmdir(folderPath); 
  220.  
  221.          } 

 

这个功能点也比较复杂, 因为没有默认的API提供,我们所能用的只是删除单个文件,所以对于删除目录的情况,我们必须递归的删除。于是,我们根据”分散难点”的思想,吧这个功能拆分为3个子方法:

(1)sftpGetFileList方法

这个方法是第一步,因为当你要递归从远程服务器指定目录删除目录时候,你必须首先要知道那个目录里面有那些文件,类似于使用FileZilla这种客户端工具时候,你可以去浏览目标机器上某目录下的所有文件。

我们在第139行定义了一个SFTPv3DirectoryEntry的List对象,然后在第141行用client.ls方法列出目标目录的所有的File,并且存入Vector中,然后从145-157航对其进行遍历,值得注意的是,因为这些操作仿造unix操作,就像我们用命令ls -l时候,它会吧当前目录"."和上层目录".."也计算在里面,所以我们必须将其排除,见第153行。

 

(2)sftpDeleteFolderRecursive方法

这个方法就是一个递归的方法,它用于递归的从远程服务器的目录删除目录。首先第183行,它调用(1)中的sftpGetFileList方法来获取了SFTPv3DirectoryEntry的List对象,然后在第187行开始遍历List对象,先在197-204行对于Entry是目录的情况进行了处理,它会递归的调用sftpDeleteFolderRecursive方法,然后在第204-211行则是对Entry是文件的情况进行了处理,直接调用已经提供的API,client.rm来移除这个文件。

 

(3)deleteFolderFromWebServer方法

这个方法是最终对外暴露的定义在接口中的方法,它在第15-39行对入参进行了检查,然后在第43-67行对于Connection对象的进行了非空检查,然后在第87行调用我们定义好的(2)中的sftpDeleteFolderResursive()方法来递归的删除远程服务器上指定目录下的某目录。

 

单元测试:

由于这个方法和deleteFileFromWebServer的行为极其相似,所以略去单元测试。