Ant ftp does not upload files to subdirectories

I am trying to upload files to subdirectories from an ftp server using ant. The exact set of files is known. Some of them are in subdirectories. Ant only seems to load those that are in the root directory. It works if I download all files without listing them.

The first ftp action should do the same as the second. Instead, I get "Hidden file \\ a \ a.txt, presumably not a symbolic link."

Does anyone know what's wrong here? Is this a bug in the ant FTP task?

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

Update: I sent an error about this to Commons Net jira https://issues.apache.org/jira/browse/NET-324

: ant bugreport https://issues.apache.org/bugzilla/show_bug.cgi?id=49296

+3
6

, . . bugreport jira: https://issues.apache.org/jira/browse/NET-324

ant bugreport 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.
+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>
+1

'/' remotedir?

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

, remotedir="" . , .

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

Apache Commons VFS Ant . / . . , sftp, ssh, http ; Ant ftp, ssh .., 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>
0

Source: https://habr.com/ru/post/1744539/


All Articles