2

在过去的几个小时里,我一直在努力解决这个问题,如果不再次下载和上传文件,我真的找不到办法。甚至可能吗?

这个问题是这个问题的一种副本:如何使用 FTP 在目录之间移动文件? 但我感觉它没有解决,虽然它已经回答了。

重命名文件本身非常容易并且没有任何问题,但是如何将其移动到另一个目录?

我有这个示例代码:

string uri2 = "ftp://ftpUser@testFtp.com/mainFolder/moveFrom/file.txt";

f = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri2));

f.Credentials = new NetworkCredential(ftpUser, ftpPass);
f.KeepAlive = false;
f.UsePassive = true;
f.Method = WebRequestMethods.Ftp.Rename;
f.Timeout = 5000;
f.UseBinary = true;

f.RenameTo = "ftp://ftpUser@testFtp.com/mainFolder/moveTo/file.txt";

FtpWebResponse response = (FtpWebResponse)f.GetResponse();

response.Close();
f.Abort();

我得到与另一个主题相同的错误:

The remote server returned an error: (550) File unavailable (e.g., file not found, no access).

使用相对路径,并没有做任何不同的事情。

我做错了什么还是从源文件夹下载,上传到目标然后从源中删除文件的唯一方法?这是对 FTP 服务器的 3 次调用。

4

1 回答 1

3

.NET 在 FTP 协议上放置了一个抽象层,它可以抽象太多,从而使某些事情变得不可能或棘手。我没有 .NET 的源代码,但基于Mono 的 FTPWebRequest的源代码(一种尝试与 .NET 兼容的实现),它将适用于 URI 上的任何操作:

  • 首先将 URI 拆分为目录部分和file_name部分(参见CWDAndSetFileName源代码)。
  • CWD 到目录。
  • 并在那里进行操作。

在 FTP 命令中重命名URL=ftp:/host/foo/bar/file1为这意味着:RenameTo=file2

... log into host ...
CWD foo/bar
RNFR file1
RNTO file2

但是,如果你在不同的目录中有源和目标,例如RenameTo=/foo/bar2/file2,你宁愿这样:

... log into host ...
RNFR foo/bar/file1
RNTO foo/bar2/file2

但不幸的是,这不是它的实现方式:(

如果幸运的话,您可以尝试使用相对路径,例如RenameTo=../bar2/file2,这应该会导致

... log into host ...
CWD foo/bar
RNFR file1
RNTO ../bar2/file2

这可能适用于 Mono-Implementation,但我不知道它是否也适用于真正的 .NET。

编辑:我刚刚查看了.NET 4.5 的源代码。它与 Mono 的不同之处在于它不会在文件操作之前对 basedir 执行 CWD,而是在名称是相对名称时将当前的 basedir 预先添加到名称中。因此,renameTo=../bar2/file2这导致

 RNFR foo/bar/file1
 RNTO foo/bar/../bar2/file2

而使用绝对名称renameTo=/bar2/file2会导致

 RNFR foo/bar/file1
 RNTO /bar2/file2

根据 FTP 服务器的类型和设置,绝对名称可能会被解释为相对于用户主目录的根目录,或者它可能是真正的绝对路径。所以最好只使用相对路径,并且解决方案../dir/应该适用于 Mono 和“真正的”.NET。

于 2014-10-23T14:47:00.523 回答