2010-05-07 77 views
3

我試圖從一個ftp服務器下載螞蟻的子目錄中的文件。 確切的文件集是已知的。 其中一些是在子目錄中。 Ant似乎只下載根目錄中的那些。 如果我下載沒有列出所有文件的文件,它可以工作。ant ftp不下載子目錄中的文件

第一個ftp操作應該完成與第二​​個完全相同的操作。 相反,我得到「隱藏文件\\ a \ a.txt假定不是符號鏈接。」

有沒有人知道這裏有什麼問題? 這是螞蟻FTP任務中的錯誤嗎?

<?xml version="1.0" encoding="utf-8"?> 
<project name="example" default="example" basedir="."> 
    <taskdef name="ftp" 
    classname="org.apache.tools.ant.taskdefs.optional.net.FTP" /> 

    <target name="example"> 

     <!-- doesn't work --> 
     <ftp action="get" verbose="true" 
     server="localhost" userid="example" password="example" 
     remotedir=""> 
      <fileset dir="downloads" casesensitive="false" 
      includes="a/a.txt,a/b/ab.txt,c/c.txt" /> 
     </ftp> 

     <!-- works (but requires multiple ftp tasks) --> 
     <ftp action="get" verbose="true" 
     server="localhost" userid="example" password="example" 
     remotedir="a"> 
      <fileset dir="downloads" casesensitive="false" 
      includes="a.txt,b/ab.txt" /> 
     </ftp> 
     <ftp action="get" verbose="true" 
     server="localhost" userid="example" password="example" 
     remotedir="c"> 
      <fileset dir="downloads" casesensitive="false" 
      includes="c.txt" /> 
     </ftp> 

    </target> 

</project> 

更新:我發佈了關於這個bug到共享網絡JIRA https://issues.apache.org/jira/browse/NET-324

更新:我添加了一個錯誤報告螞蟻錯誤報告系統https://issues.apache.org/bugzilla/show_bug.cgi?id=49296

回答

1

我相信已經找到並解決了問題。 也看到我的錯誤報告在JIRA:https://issues.apache.org/jira/browse/NET-324

,我添加了一個錯誤報告螞蟻錯誤報告系統https://issues.apache.org/bugzilla/show_bug.cgi?id=49296

diff --git a/libs/apache-ant-1.8.1/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java b/libs/apache-ant-1.8.1/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java 
--- a/libs/apache-ant-1.8.1/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java 
+++ b/libs/apache-ant-1.8.1/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java 
@@ -834,8 +834,7 @@ 
         } else if (!result) { 
          return; 
         } 
-      this.curpwd = this.curpwd + remoteFileSep 
-       + currentPathElement; 
+      this.curpwd = getCurpwdPlusFileSep() + currentPathElement; 
        } catch (IOException ioe) { 
         throw new BuildException("could not change working dir to " 
                + (String) pathElements.elementAt(fcount) 
@@ -895,7 +894,7 @@ 
       * @return absolute path as string 
       */ 
      public String getAbsolutePath() { 
-    return curpwd + remoteFileSep + ftpFile.getName(); 
+    return getCurpwdPlusFileSep() + ftpFile.getName(); 
      } 
      /** 
       * find out the relative path assuming that the path used to construct 
@@ -1036,6 +1035,17 @@ 
      public String getCurpwd() { 
       return curpwd; 
      } 
+ 
+   /** 
+    * @return parent directory of the AntFTPFile with a remoteFileSep appended 
+    */ 
+   private String getCurpwdPlusFileSep() { 
+    if (this.curpwd.endsWith(remoteFileSep)) { 
+     return this.curpwd; 
+    } 
+    return this.curpwd + remoteFileSep; 
+   } 
+    
      /** 
       * find out if a symbolic link is encountered in the relative path of this file 
       * from rootPath. 
0

你已經嘗試將'/'設置爲remotedir的值?

<ftp action="get" verbose="true" 
    server="localhost" userid="example" password="example" 
    remotedir="/"> 
    <fileset dir="downloads" casesensitive="false" 
    includes="a/a.txt" /> 
</ftp> 
+0

是我做到了。這並不能解決問題。 – 2010-05-10 16:51:34

0

我不知道設置remotedir=""是合法的。如果你想使用默認的根目錄,那麼你應該完全放棄它。

+0

我也試過。它不起作用。 – 2010-05-12 08:25:22

1

因爲我需要這個工作,所以我做了這個解決方法。 它似乎工作,但我並不完全滿意。 它不覺得乾淨。

<scriptdef name="my-ftp-get" language="javascript"> 
    <attribute name="server"/> 
    <attribute name="userid"/> 
    <attribute name="password"/> 
    <attribute name="remotedir"/> 
    <attribute name="fileset_dir"/> 
    <attribute name="fileset_includes"/> 
    <![CDATA[ 
    importClass(java.io.File); 
    importClass(org.apache.tools.ant.taskdefs.optional.net.FTP); 
    var local_basedir = "" + attributes.get("fileset_dir") + "/"; 
    var original_includes = "" + attributes.get("fileset_includes"); 
    var remotedir = "" + attributes.get("remotedir"); 
    local_basedir = local_basedir.replace(/\\/g, "/"); 
    original_includes = original_includes.replace(/\\/g, "/"); 
    remotedir = remotedir.replace(/\\/g, "/"); 
    var includes_arr = original_includes.split(","); 
    var clean_includes = {}; 
    for (var i = 0; i < includes_arr.length; i++) { 
     var directory = "/"; 
     var filename = includes_arr[i]; 
     var split_include = includes_arr[i].split("/"); 
     if (split_include.length > 1) { 
      directory = split_include[0] + "/"; 
      filename = includes_arr[i].substring(directory.length); 
     } 
     if (!clean_includes.hasOwnProperty(directory)) { 
      clean_includes[directory] = []; 
     } 
     clean_includes[directory].push(filename); 
    } 
    var get_files = new FTP.Action(); 
    get_files.setValue("get"); 
    for (var path in clean_includes) { 
     var current_clean_includes = clean_includes[path].join(","); 
     var fileset = project.createDataType("fileset"); 
     var ftp = self.project.createTask("ftp"); 
     ftp.setAction(get_files); 
     ftp.setServer(attributes.get("server")); 
     ftp.setUserid(attributes.get("userid")); 
     ftp.setPassword(attributes.get("password")); 
     ftp.setRemotedir(remotedir + path); 
     fileset.setDir(new File(local_basedir + path)); 
     fileset.setIncludes(current_clean_includes); 
     ftp.addFileset(fileset); 
     ftp.perform(); 
    } 
    ]]> 
</scriptdef> 

<my-ftp-get 
server="localhost" userid="example" password="example" 
remotedir="" 
    fileset_dir="downloads" casesensitive="false" 
    fileset_includes="a/a.txt,a/b/ab.txt"> 
</my-ftp-get> 
0

第一種情況會試圖獲取文件//downloads/a/a.txt 第二種情況將嘗試獲取文件//a/downloads/a.txt

如果您更換一個不與

<ftp action="get" verbose="true" 
    server="localhost" userid="example" password="example" 
    remotedir=""> 
     <fileset dir="a/downloads" casesensitive="false" 
     includes="a.txt" /> 
</ftp> 

<ftp action="get" verbose="true" 
    server="localhost" userid="example" password="example" 
    remotedir=""> 
     <fileset dir="a" casesensitive="false" 
     includes="downloads/a.txt" /> 
</ftp> 

工作應該更好地工作。如果這些不適合你的需求,你可以提供你想匹配的文件的完整路徑,也許我們可以創建一些替代品。

+0

不,你混淆了remoteDir和文件集目錄屬性。引用手冊:「從FTP服務器獲取文件的方式與發送文件的方式幾乎相同,唯一的區別是嵌套文件集使用remotedir屬性作爲FTP服務器上文件的基本目錄,而dir屬性作爲本地目錄來放置文件。「 – 2010-05-12 15:31:14

+0

我想下載根目錄下的幾個文件和不同子目錄下的幾個文件。舉個例子:root.txt,a/a.txt,a/b/ab.txt,c/c.txt – 2010-05-12 15:36:28

0

您可能在Apache Commons VFS Ant Tasks上獲得了更多成功。這些提供讀/寫到各種文件系統,並進行復制。同步和其他操作。如果您以後需要更改爲使用sftp,ssh,http或其他系統,這也將是一個靈活的解決方案;與ftp,ssh等的本地ant任務不同,大多數VFS配置獨立於文件系統,文件系統特定主要只需要更改URL。

你的例子就是沿着這些線路編碼:

<taskdef resource="org/apache/commons/vfs/tasks/tasks.properties"/> 

<target name="example"> 
    <v-copy destdir="${basedir}" srcdir="ftp://example:[email protected]/downloads" includes="a/a.txt,a/b/ab.txt,c/c.txt"/> 
</target>