Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ant ftp不';t下载子目录中的文件_Ant_Ftp_Apache Commons Net - Fatal编程技术网

ant ftp不';t下载子目录中的文件

ant ftp不';t下载子目录中的文件,ant,ftp,apache-commons-net,Ant,Ftp,Apache Commons Net,我试图用ant从ftp服务器下载子目录中的文件。 确切的文件集是已知的。 其中一些在子目录中。 Ant似乎只下载根目录中的文件。 如果我下载所有文件而不列出它们,那么它确实可以工作 第一个ftp操作应与第二个ftp操作执行完全相同的操作。 相反,我得到的是“假定不是符号链接的隐藏文件\\a\a.txt” 有人知道这里出了什么问题吗? 这是ant FTP任务中的错误吗 <?xml version="1.0" encoding="utf-8"?> <project name="ex

我试图用ant从ftp服务器下载子目录中的文件。 确切的文件集是已知的。 其中一些在子目录中。 Ant似乎只下载根目录中的文件。 如果我下载所有文件而不列出它们,那么它确实可以工作

第一个ftp操作应与第二个ftp操作执行完全相同的操作。 相反,我得到的是“假定不是符号链接的隐藏文件\\a\a.txt”

有人知道这里出了什么问题吗? 这是ant 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>

更新:我向Commons Net jira发布了一个关于此的bug


更新:我在ant bugreport系统中添加了一个bugreport

您是否已经尝试将“/”设置为remotedir的值

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


我不知道设置
remotedir=“”
是否合法。如果你想使用默认的根目录,那么你应该完全不使用它。

因为我需要它来工作,所以我做了这个变通方法。 这似乎有效,但我并不完全满意。 感觉不干净

<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>

1) {
directory=split_include[0]+“/”;
filename=includes_arr[i]。子字符串(directory.length);
}
如果(!clean_includes.hasOwnProperty(目录)){
clean_包括[目录]=[];
}
clean_包括[directory].push(文件名);
}
var get_files=new FTP.Action();
get_files.setValue(“get”);
for(clean_中的var路径包括){
var current_clean_includes=clean_includes[path]。连接(“,”;
var fileset=project.createDataType(“fileset”);
var ftp=self.project.createTask(“ftp”);
setAction(获取文件);
setServer(attributes.get(“server”);
setUserid(attributes.get(“userid”);
setPassword(attributes.get(“password”);
ftp.setRemotedir(remotedir+path);
setDir(新文件(local_basedir+path));
setIncludes(当前\u clean\u包括);
ftp.addFileset(fileset);
ftp.perform();
}
]]>

第一个案例将尝试获取文件//下载/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>



它应该更有效。如果这些不符合您的需要,您能否提供您想要匹配的文件的完整路径,或许我们可以创建一些替代方案。

您可能会在使用中获得更大的成功。它们提供对各种文件系统的读/写,以及复制。同步和其他操作。如果您以后需要更改为使用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:example@localhost/downloads" includes="a/a.txt,a/b/ab.txt,c/c.txt"/>
</target>

我相信我已经发现并解决了这个问题。 另请参见jira中的错误报告:

我在ant bugreport系统中添加了一个bugreport


不,您混淆了remoteDir和fileset dir属性。引用该手册:“从FTP服务器获取文件的方式与发送文件的方式基本相同。唯一的区别是,嵌套文件集使用remotedir属性作为FTP服务器上文件的基本目录,使用dir属性作为将文件放入的本地目录。”我想在根目录下下载几个文件,在不同的子目录下下载几个文件。举个例子:root.txt、a/a.txt、a/b/ab.txt、c/c.txt
<taskdef resource="org/apache/commons/vfs/tasks/tasks.properties"/>

<target name="example">
     <v-copy destdir="${basedir}" srcdir="ftp://example:example@localhost/downloads" includes="a/a.txt,a/b/ab.txt,c/c.txt"/>
</target>
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.