Ganymed SSH-2 for Java系列7之删除远程服务器上的非空目录(方法说明)

来源:互联网 发布:黄金分析软件哪个好 编辑:程序博客网 时间:2024/04/26 10:51

首先大家看看这段java代码的打印结果:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. Vector v1 = sftpClient.ls(remoteDerectory);  
  2.          for (Iterator iterator2 = v1.iterator(); iterator2  
  3.          .hasNext();) {  
  4.          SFTPv3DirectoryEntry ob = (SFTPv3DirectoryEntry)  
  5.          iterator2.next();  
  6.           
  7.          System.out.println("--------******************----------");  
  8.          System.out.println("ob.longEntry is:" + ob.longEntry);  
  9.          System.out.println("ob.filename is:" + ob.filename);  
  10.          System.out.println("ob.attributes.isDirectory() is:"  
  11.          + ob.attributes.isDirectory());  
  12.          System.out.println("ob.attributes.size is:"  
  13.          + ob.attributes.size);  
  14.          System.out.println("--------******************----------");  
  15.          }  
  16.           
  17.          }  


结果:
--------******************----------
ob.longEntry is:drwxr-xr-x    3 root     root         4096 Mar  3 09:32 .
ob.filename is:.
ob.attributes.isDirectory() is:true
ob.attributes.size is:4096
--------******************----------
--------******************----------
ob.longEntry is:drwxr-xr-x    3 root     root         4096 Mar  3 09:31 ..
ob.filename is:..
ob.attributes.isDirectory() is:true
ob.attributes.size is:4096
--------******************----------
--------******************----------
ob.longEntry is:drwxr-xr-x    2 root     root         4096 Mar  3 09:32 t
ob.filename is:t
ob.attributes.isDirectory() is:true
ob.attributes.size is:4096
--------******************----------
--------******************----------
ob.longEntry is:-rw-r--r--    1 root     root            6 Mar  3 09:31 t.txt
ob.filename is:t.txt
ob.attributes.isDirectory() is:false
ob.attributes.size is:6
--------******************----------


故才有之前的方法:


[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. List<String> filelist = new ArrayList<String>();  
  2.   
  3.             List<String> direlist = new ArrayList<String>();  
  4.             direlist.add(remoteDerectory);  

定义存放文件和目录的List,其存放的是全路径:

如:

fileLIst:

/usr/local/test/tt.txt


direlist:
/usr/local/test/tt/t


列出所有目录和文件信息:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. Vector v = sftpClient.ls(remoteDerectory);  

遍历目录和文件信息,存入定义好的对象中:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. getUrlPath(sftpClient, filelist, direlist, remoteDerectory);  

逆向删除目录和文件:


[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. System.out.println("file list is::");  
  2.         for (int i = filelist.size() - 1; i > -1; i--) {  
  3.             System.out.println(filelist.get(i));  
  4.             sftpClient.rm(filelist.get(i));  
  5.         }  
  6.   
  7.         System.out.println("directory list is::");  
  8.         for (int i = direlist.size() - 1; i > -1; i--) {  
  9.             System.out.println(direlist.get(i));  
  10.             sftpClient.rmdir(direlist.get(i));  
  11.         }  


这个和之前存入list的顺序有关;


[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. private static void getUrlPath(SFTPv3Client sftpClient,  
  2.             List<String> filelist, List<String> direlist, String remoteDerectory)  
  3.             throws IOException {  
  4.   
  5.         Vector v = sftpClient.ls(remoteDerectory);  
  6.         for (Iterator iterator = v.iterator(); iterator.hasNext();) {  
  7.             SFTPv3DirectoryEntry object = (SFTPv3DirectoryEntry) iterator  
  8.                     .next();  
  9.             System.out.println(object.filename);  
  10.             if (object.attributes.isDirectory()  
  11.                     && object.filename.indexOf(".") == -1) {  
  12.                 String rderectory = remoteDerectory + "/" + object.filename;  
  13.                 direlist.add(rderectory);  
  14.                 getUrlPath(sftpClient, filelist, direlist, rderectory);  
  15.   
  16.             } else if (!object.filename.startsWith(".")  
  17.                     && !object.filename.endsWith(".")) {  
  18.                 String path = remoteDerectory + "/" + object.filename;  
  19.                 filelist.add(path);  
  20.             }  
  21.         }  
  22.   
  23.     }  

这个方法内部有个递归调用,将所有的文件和目录信息存入对应的对象中;


[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. if (!object.filename.startsWith(".")  
  2.                     && !object.filename.endsWith("."))  

这个判断主要是排除:

--------******************----------
ob.longEntry is:drwxr-xr-x    3 root     root         4096 Mar  3 09:31 ..
ob.filename is:..
ob.attributes.isDirectory() is:true
ob.attributes.size is:4096
--------******************----------

类似这样的信息;判断不严格。


我们再看看:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. Vector v = sftpClient.ls(remoteDerectory);  
  2. for (Iterator iterator = v.iterator(); iterator.hasNext();) {  
  3.             SFTPv3DirectoryEntry object = (SFTPv3DirectoryEntry) iterator  
  4.                     .next();  

为什么Vector中存放的是
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. SFTPv3DirectoryEntry   

这个对象,可以查看源码:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * List the contents of a directory. 
  3.  *  
  4.  * @param dirName See the {@link SFTPv3Client comment} for the class for more details. 
  5.  * @return A Vector containing {@link SFTPv3DirectoryEntry} objects. 
  6.  * @throws IOException 
  7.  */  
  8. public Vector ls(String dirName) throws IOException  
  9. {  
  10.     byte[] handle = openDirectory(dirName);  
  11.     Vector result = scanDirectory(handle);  
  12.     closeHandle(handle);  
  13.     return result;  
  14. }  
继续查看:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <pre code_snippet_id="214433" snippet_file_name="blog_20140303_11_8007701" name="code" class="java">Vector result = scanDirectory(handle);</pre><p></p>  
  2. <pre></pre>  
  3. <p></p>  
  4. <p><br>  
  5. </p>  
  6. <pre code_snippet_id="214433" snippet_file_name="blog_20140303_12_8672793" name="code" class="java">private final Vector scanDirectory(byte[] handle) throws IOException  
  7.     {  
  8.         Vector files = new Vector();  
  9.   
  10.         while (true)  
  11.         {  
  12.             int req_id = generateNextRequestID();  
  13.   
  14.             TypesWriter tw = new TypesWriter();  
  15.             tw.writeString(handle, 0, handle.length);  
  16.   
  17.             if (debug != null)  
  18.             {  
  19.                 debug.println("Sending SSH_FXP_READDIR...");  
  20.                 debug.flush();  
  21.             }  
  22.   
  23.             sendMessage(Packet.SSH_FXP_READDIR, req_id, tw.getBytes());  
  24.   
  25.             byte[] resp = receiveMessage(34000);  
  26.   
  27.             if (debug != null)  
  28.             {  
  29.                 debug.println("Got REPLY.");  
  30.                 debug.flush();  
  31.             }  
  32.   
  33.             TypesReader tr = new TypesReader(resp);  
  34.   
  35.             int t = tr.readByte();  
  36.   
  37.             int rep_id = tr.readUINT32();  
  38.             if (rep_id != req_id)  
  39.                 throw new IOException("The server sent an invalid id field.");  
  40.   
  41.             if (t == Packet.SSH_FXP_NAME)  
  42.             {  
  43.                 int count = tr.readUINT32();  
  44.   
  45.                 if (debug != null)  
  46.                     debug.println("Parsing " + count + " name entries...");  
  47.   
  48.                 while (count > 0)  
  49.                 {  
  50.                     SFTPv3DirectoryEntry dirEnt = new SFTPv3DirectoryEntry();  
  51.   
  52.                     dirEnt.filename = tr.readString(charsetName);  
  53.                     dirEnt.longEntry = tr.readString(charsetName);  
  54.   
  55.                     dirEnt.attributes = readAttrs(tr);  
  56.                     files.addElement(dirEnt);  
  57.   
  58.                     if (debug != null)  
  59.                         debug.println("File: '" + dirEnt.filename + "'");  
  60.                     count--;  
  61.                 }  
  62.                 continue;  
  63.             }  
  64.   
  65.             if (t != Packet.SSH_FXP_STATUS)  
  66.                 throw new IOException("The SFTP server sent an unexpected packet type (" + t + ")");  
  67.   
  68.             int errorCode = tr.readUINT32();  
  69.   
  70.             if (errorCode == ErrorCodes.SSH_FX_EOF)  
  71.                 return files;  
  72.   
  73.             throw new SFTPException(tr.readString(), errorCode);  
  74.         }  
  75.     }</pre><br>  
  76. 首先定义了:  
  77. <p></p><pre code_snippet_id="214433" snippet_file_name="blog_20140303_13_4529118" name="code" class="java">Vector files = new Vector();</pre><br>  
  78. 最后存放的是:<p></p>  
  79. <p></p><pre code_snippet_id="214433" snippet_file_name="blog_20140303_14_1813903" name="code" class="java">files.addElement(dirEnt);</pre><br>  
  80. <p></p>  
  81. <p>在看看:SFTPv3DirectoryEntry对象定义:</p>  
  82. <p></p><pre code_snippet_id="214433" snippet_file_name="blog_20140303_15_6590432" name="code" class="java">public class SFTPv3DirectoryEntry  
  83. {  
  84.     /** 
  85.      *  A relative name within the directory, without any path components. 
  86.      */  
  87.     public String filename;  
  88.   
  89.     /** 
  90.      * An expanded format for the file name, similar to what is returned by 
  91.      * "ls -l" on Un*x systems. 
  92.      * <p> 
  93.      * The format of this field is unspecified by the SFTP v3 protocol. 
  94.      * It MUST be suitable for use in the output of a directory listing 
  95.      * command (in fact, the recommended operation for a directory listing 
  96.      * command is to simply display this data).  However, clients SHOULD NOT 
  97.      * attempt to parse the longname field for file attributes; they SHOULD 
  98.      * use the attrs field instead. 
  99.      * <p> 
  100.      * The recommended format for the longname field is as follows:<br> 
  101.      * <code>-rwxr-xr-x   1 mjos     staff      348911 Mar 25 14:29 t-filexfer</code> 
  102.      */  
  103.     public String longEntry;  
  104.   
  105.     /** 
  106.      * The attributes of this entry. 
  107.      */  
  108.     public SFTPv3FileAttributes attributes;</pre><br>  
  109. 其包含了三个基本属性,分别是:<p></p>  
  110. <p>filename 文件或者目录名称;<br>  
  111. </p>  
  112. <p>longEntry  目录(d)权限等基本信息:例如:drwxr-xr-x    2 root     root         4096 Mar  3 09:32 t 或者 -rw-r--r--    1 root     root            3 Mar  3 09:31 tt.txt<br>  
  113. </p>  
  114. <p>SFTPv3FileAttributes 定义了entry 属性对象,存放是否是目录,权限等基础信息;<br>  
  115. </p>  
  116. <p><br>  
  117. </p>  
  118. <p>继续查看源码:<br>  
  119. </p>  
  120. <p></p><pre code_snippet_id="214433" snippet_file_name="blog_20140303_16_3003165" name="code" class="java">public class SFTPv3FileAttributes  
  121. {  
  122.     /** 
  123.      * The SIZE attribute. <code>NULL</code> if not present. 
  124.      */  
  125.     public Long size = null;  
  126.   
  127.     /** 
  128.      * The UID attribute. <code>NULL</code> if not present. 
  129.      */  
  130.     public Integer uid = null;  
  131.   
  132.     /** 
  133.      * The GID attribute. <code>NULL</code> if not present. 
  134.      */  
  135.     public Integer gid = null;  
  136.   
  137.     /** 
  138.      * The POSIX permissions. <code>NULL</code> if not present. 
  139.      * <p> 
  140.      * Here is a list: 
  141.      * <p> 
  142.      * <pre>Note: these numbers are all OCTAL. 
  143.      *   
  144.      *  S_IFMT     0170000   bitmask for the file type bitfields 
  145.      *  S_IFSOCK   0140000   socket 
  146.      *  S_IFLNK    0120000   symbolic link 
  147.      *  S_IFREG    0100000   regular file 
  148.      *  S_IFBLK    0060000   block device 
  149.      *  S_IFDIR    0040000   directory 
  150.      *  S_IFCHR    0020000   character device 
  151.      *  S_IFIFO    0010000   fifo  
  152.      *  S_ISUID    0004000   set UID bit 
  153.      *  S_ISGID    0002000   set GID bit  
  154.      *  S_ISVTX    0001000   sticky bit 
  155.      *   
  156.      *  S_IRWXU    00700     mask for file owner permissions 
  157.      *  S_IRUSR    00400     owner has read permission 
  158.      *  S_IWUSR    00200     owner has write permission 
  159.      *  S_IXUSR    00100     owner has execute permission 
  160.      *  S_IRWXG    00070     mask for group permissions 
  161.      *  S_IRGRP    00040     group has read permission 
  162.      *  S_IWGRP    00020     group has write permission 
  163.      *  S_IXGRP    00010     group has execute permission 
  164.      *  S_IRWXO    00007     mask for permissions for others (not in group) 
  165.      *  S_IROTH    00004     others have read permission 
  166.      *  S_IWOTH    00002     others have write permisson 
  167.      *  S_IXOTH    00001     others have execute permission 
  168.      * </pre> 
  169.      */  
  170.     public Integer permissions = null;  
  171.   
  172.     /** 
  173.      * The ATIME attribute. Represented as seconds from Jan 1, 1970 in UTC. 
  174.      * <code>NULL</code> if not present. 
  175.      */  
  176.     public Integer atime = null;  
  177.   
  178.     /** 
  179.      * The MTIME attribute. Represented as seconds from Jan 1, 1970 in UTC. 
  180.      * <code>NULL</code> if not present. 
  181.      */  
  182.     public Integer mtime = null;  
  183.   
  184.     /** 
  185.      * Checks if this entry is a directory. 
  186.      *  
  187.      * @return Returns true if permissions are available and they indicate 
  188.      *         that this entry represents a directory. 
  189.      */  
  190.     public boolean isDirectory()  
  191.     {  
  192.         if (permissions == null)  
  193.             return false;  
  194.           
  195.         return ((permissions.intValue() & 0040000) != 0);  
  196.     }  
  197.       
  198.     /** 
  199.      * Checks if this entry is a regular file. 
  200.      *  
  201.      * @return Returns true if permissions are available and they indicate 
  202.      *         that this entry represents a regular file. 
  203.      */  
  204.     public boolean isRegularFile()  
  205.     {  
  206.         if (permissions == null)  
  207.             return false;  
  208.           
  209.         return ((permissions.intValue() & 0100000) != 0);  
  210.     }  
  211.       
  212.     /** 
  213.      * Checks if this entry is a a symlink. 
  214.      *  
  215.      * @return Returns true if permissions are available and they indicate 
  216.      *         that this entry represents a symlink. 
  217.      */  
  218.     public boolean isSymlink()  
  219.     {  
  220.         if (permissions == null)  
  221.             return false;  
  222.           
  223.         return ((permissions.intValue() & 0120000) != 0);  
  224.     }  
  225.       
  226.     /** 
  227.      * Turn the POSIX permissions into a 7 digit octal representation. 
  228.      * Note: the returned value is first masked with <code>0177777</code>. 
  229.      *  
  230.      * @return <code>NULL</code> if permissions are not available. 
  231.      */  
  232.     public String getOctalPermissions()  
  233.     {  
  234.         if (permissions == null)  
  235.             return null;  
  236.   
  237.         String res = Integer.toString(permissions.intValue() & 01777778);  
  238.   
  239.         StringBuffer sb = new StringBuffer();  
  240.   
  241.         int leadingZeros = 7 - res.length();  
  242.   
  243.         while (leadingZeros > 0)  
  244.         {  
  245.             sb.append('0');  
  246.             leadingZeros--;  
  247.         }  
  248.   
  249.         sb.append(res);  
  250.   
  251.         return sb.toString();  
  252.     }  
  253. }</pre><br>  
  254. 这个里面基本定义了权限,是否是目录等基本信息;
0 0
原创粉丝点击