我正在尝试使用ant从ftp服务器下载子目录中的文件。 确切的文件集是已知的。 其中一些是在子目录中。 Ant似乎只下载根目录中的那些。 如果我下载所有文件而不列出它们,它确实有效。
第一个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>
更新:我向Commons Net jira发布了一个关于此问题的错误 https://issues.apache.org/jira/browse/NET-324
更新:我在ant bug报告系统中添加了一个bug报告https://issues.apache.org/bugzilla/show_bug.cgi?id=49296
答案 0 :(得分: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 :(得分:1)
我相信找到并解决了这个问题。 另请参阅jira中的bug报告:https://issues.apache.org/jira/browse/NET-324
我已经向ant bugreport system https://issues.apache.org/bugzilla/show_bug.cgi?id=49296
添加了一个bug报告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.
答案 2 :(得分:0)
您是否已尝试将'/'设为remotedir的值?
<ftp action="get" verbose="true"
server="localhost" userid="example" password="example"
remotedir="/">
<fileset dir="downloads" casesensitive="false"
includes="a/a.txt" />
</ftp>
答案 3 :(得分:0)
我不知道设置remotedir=""
是合法的。如果你想使用默认的根目录,那么你应该完全不用它。
答案 4 :(得分: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>
它应该更好。如果这些不符合您的需求,您可以提供您想要匹配的文件的完整路径,也许我们可以创建一些替代方案。
答案 5 :(得分: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:example@localhost/downloads" includes="a/a.txt,a/b/ab.txt,c/c.txt"/>
</target>