2011-02-01 185 views
16

我有一个程序需要将文件从FTP服务器上的一个目录移动到另一个目录。例如,该文件是:如何使用FTP在目录之间移动文件?

ftp://1.1.1.1/MAIN/Dir1 

,我需要将文件移动到:

ftp://1.1.1.1/MAIN/Dir2 

我发现一对夫妇的文章推荐使用重命名命令,所以我尝试了以下内容:

Uri serverFile = new Uri(“ftp://1.1.1.1/MAIN/Dir1/MyFile.txt"); 
    FtpWebRequest reqFTP= (FtpWebRequest)FtpWebRequest.Create(serverFile); 
    reqFTP.Method = WebRequestMethods.Ftp.Rename; 
    reqFTP.UseBinary = true; 
    reqFTP.Credentials = new NetworkCredential(ftpUser, ftpPass); 
    reqFTP.RenameTo = “ftp://1.1.1.1/MAIN/Dir2/MyFile.txt"; 

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

但是这似乎并没有工作 - 我得到以下错误:

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

起初我以为这可能与权限有关,但据我所见,我有权访问整个FTP站点(它位于本地PC上,uri已解析为本地主机)。

是否应该可以在这样的目录之间移动文件,如果没有,它怎么可能?

解决一些已经提出的问题/建议:

  1. 我可以从源目录下载同一个文件,所以它肯定存在(我在做什么,首先下载该文件,然后将它移到其他地方)。
  2. 我可以从浏览器(包括源和目标目录)访问ftp站点
  3. ftp服务器在我本地机器上的我自己的IIS实例下运行。
  4. 路径和大小写是正确的,没有特殊字符。

此外,我已经尝试设置目录路径是:

ftp://1.1.1.1/%2fMAIN/Dir1/MyFile.txt 

两个源和目标路径 - 但是这并没有区别两种。

我发现this文章,似乎说,指定目的地作为相对路径会有所帮助 - 它似乎不可能指定绝对路径作为目的地。

reqFTP.RenameTo = “../Dir2/MyFile.txt"; 
+1

如果您将ftp://1.1.1.1/MAIN/Dir1/MyFile.txt插入到浏览器中,它是否正常工作? – 2011-02-01 16:12:19

+0

该路径是否包含需要转义的特殊字符? – 2011-02-01 16:18:11

+0

查看最新编辑内容,但答案是:是 - 它可以在浏览器中正常工作,否 - 路径中没有特殊字符 – 2011-02-02 07:45:15

回答

10

MSDN似乎表明,你的路径被认为是相对的,因此它会尝试使用所提供的凭证登录到FTP服务器,然后将当前目录设置到<UserLoginDirectory>/path目录。如果这不是你的文件所在的目录,那么你会得到一个550错误。

+0

查看最新编辑。我尝试过%2f在路径中的各种组合,但没有成功 – 2011-02-02 10:03:09

0

您是否有FTP服务中定义的文件夹? FTP服务正在运行?如果两个问题的答案都是否定的,则不能使用FTP来移动文件。

尝试在FTP客户端打开FTP文件夹,看看会发生什么。如果仍然存在错误,则说明您的定义有问题,因为FTP服务没有看到该文件夹​​,或者该文件夹在逻辑上不在您认为它在FTP服务中的位置。

您还可以打开IIS管理器,并查看FTP中的设置。

至于其他移动文件的方法,只要运行程序的账户对两者都有适当的权限,就可以轻松地从UNC路径移动到另一个路径。 UNC路径类似于HTTP或FTP路径,并且方向相反,没有指定协议。

0

该代码看起来正确。所以要么你有错误的路径,文件DOESNT存在,或者你需要尊重大小写(显然Windows不区分大小写,但是Linux,Unix)。

您是否尝试在浏览器中打开该文件?打开Windows文件资源管理器,在路径栏中输入地址,看看你得到了什么。

1

我能得到这个工作,但只有在RenameTo因为它存在使用路径在服务器上,即/DRIVELETTER:/FOLDERNAME/filename =“

1

如果你只有绝对路径?

好吧,我来了因为我得到了同样的错误,答案似乎是使用相对路径,这对于我的问题来说并不是很好,因为我得到的文件夹路径是绝对路径字符串。解决方案我在飞行工作中遇到了难题,但至少可以说这是一个社区维基答案,如果有的话ne有更好的解决方案,随时编辑这个。

由于我学到了这个,我有2个解决方案。

  1. 将移动到路径的绝对路径,并将其转换为相对URL。

    public static string GetRelativePath(string ftpBasePath, string ftpToPath) 
    { 
    
        if (!ftpBasePath.StartsWith("/")) 
        { 
         throw new Exception("Base path is not absolute"); 
        } 
        else 
        { 
         ftpBasePath = ftpBasePath.Substring(1); 
        } 
        if (ftpBasePath.EndsWith("/")) 
        { 
         ftpBasePath = ftpBasePath.Substring(0, ftpBasePath.Length - 1); 
        } 
    
        if (!ftpToPath.StartsWith("/")) 
        { 
         throw new Exception("Base path is not absolute"); 
        } 
        else 
        { 
         ftpToPath = ftpToPath.Substring(1); 
        } 
        if (ftpToPath.EndsWith("/")) 
        { 
         ftpToPath = ftpToPath.Substring(0, ftpToPath.Length - 1); 
        } 
        string[] arrBasePath = ftpBasePath.Split("/".ToCharArray()); 
        string[] arrToPath = ftpToPath.Split("/".ToCharArray()); 
    
        int basePathCount = arrBasePath.Count(); 
        int levelChanged = basePathCount; 
        for (int iIndex = 0; iIndex < basePathCount; iIndex++) 
        { 
         if (arrToPath.Count() > iIndex) 
         { 
          if (arrBasePath[iIndex] != arrToPath[iIndex]) 
          { 
           levelChanged = iIndex; 
           break; 
          } 
         } 
        } 
        int HowManyBack = basePathCount - levelChanged; 
        StringBuilder sb = new StringBuilder(); 
        for (int i = 0; i < HowManyBack; i++) 
        { 
         sb.Append("../"); 
        } 
        for (int i = levelChanged; i < arrToPath.Count(); i++) 
        { 
         sb.Append(arrToPath[i]); 
         sb.Append("/"); 
        } 
    
        return sb.ToString(); 
    } 
    
    public static string MoveFile(string ftpuri, string username, string password, string ftpfrompath, string ftptopath, string filename) 
    { 
        string retval = string.Empty; 
    
        FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(ftpuri + ftpfrompath + filename); 
        ftp.Method = WebRequestMethods.Ftp.Rename; 
        ftp.Credentials = new NetworkCredential(username, password); 
        ftp.UsePassive = true; 
        ftp.RenameTo = GetRelativePath(ftpfrompath, ftptopath) + filename; 
        Stream requestStream = ftp.GetRequestStream(); 
    
    
        FtpWebResponse ftpresponse = (FtpWebResponse)ftp.GetResponse(); 
    
        Stream responseStream = ftpresponse.GetResponseStream(); 
    
        StreamReader reader = new StreamReader(responseStream); 
    
        return reader.ReadToEnd(); 
    } 
    

或...

  1. 从路径中的 “从FTP” 下载文件,上传到 “ftp到” 路径,并从 “从FTP” 删除路径。

    public static string SendFile(string ftpuri, string username, string password, string ftppath, string filename, byte[] datatosend) 
    { 
        if (ftppath.Substring(ftppath.Length - 1) != "/") 
        { 
         ftppath += "/"; 
        } 
        FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(ftpuri + ftppath + filename); 
        ftp.Method = WebRequestMethods.Ftp.UploadFile; 
        ftp.Credentials = new NetworkCredential(username, password); 
        ftp.UsePassive = true; 
        ftp.ContentLength = datatosend.Length; 
        Stream requestStream = ftp.GetRequestStream(); 
        requestStream.Write(datatosend, 0, datatosend.Length); 
        requestStream.Close(); 
    
        FtpWebResponse ftpresponse = (FtpWebResponse)ftp.GetResponse(); 
    
        return ftpresponse.StatusDescription; 
    } 
    public static string DeleteFile(string ftpuri, string username, string password, string ftppath, string filename) 
    { 
    
        FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(ftpuri + ftppath + filename); 
        ftp.Method = WebRequestMethods.Ftp.DeleteFile; 
        ftp.Credentials = new NetworkCredential(username, password); 
        ftp.UsePassive = true; 
    
        FtpWebResponse response = (FtpWebResponse)ftp.GetResponse(); 
    
        Stream responseStream = response.GetResponseStream(); 
    
        StreamReader reader = new StreamReader(responseStream); 
    
        return reader.ReadToEnd(); 
    } 
    public static string MoveFile(string ftpuri, string username, string password, string ftpfrompath, string ftptopath, string filename) 
    { 
        string retval = string.Empty; 
        byte[] filecontents = GetFile(ftpuri, username, password, ftpfrompath, filename); 
        retval += SendFile(ftpuri, username, password, ftptopath, filename, filecontents); 
        retval += DeleteFile(ftpuri, username, password, ftpfrompath, filename); 
        return retval; 
    } 
    
16

有同样的问题,发现另一种方式来解决这个问题:

public string FtpRename(string source, string destination) { 
     if (source == destination) 
      return; 

     Uri uriSource = new Uri(this.Hostname + "/" + source), UriKind.Absolute); 
     Uri uriDestination = new Uri(this.Hostname + "/" + destination), UriKind.Absolute); 

     // Do the files exist? 
     if (!FtpFileExists(uriSource.AbsolutePath)) { 
      throw (new FileNotFoundException(string.Format("Source '{0}' not found!", uriSource.AbsolutePath))); 
     } 

     if (FtpFileExists(uriDestination.AbsolutePath)) { 
      throw (new ApplicationException(string.Format("Target '{0}' already exists!", uriDestination.AbsolutePath))); 
     } 

     Uri targetUriRelative = uriSource.MakeRelativeUri(uriDestination); 


     //perform rename 
     FtpWebRequest ftp = GetRequest(uriSource.AbsoluteUri); 
     ftp.Method = WebRequestMethods.Ftp.Rename; 
     ftp.RenameTo = Uri.UnescapeDataString(targetUriRelative.OriginalString); 

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

     return response.StatusDescription; 

    } 
-2

我上同一类型的项目工作,尝试建立一个Web服务,可以移动的文件并在您的文件所在的服务器上运行。使用参数构建它以传入文件名。当写入开始你可能要追加价值的文件名的文件,说相关的文件等

1

在下面的代码示例中,我试着用以下数据和它的工作数据的PK。

FTP登录位置是 “C:\ FTP”。

文件原来的位置 “C:\ FTP \ DATA \ FTP.txt”。

文件被移动, “C:\ FTP \移动\ FTP.txt”。

Uri serverFile = new Uri(“ftp://localhost/Data/FTP.txt"); 
FtpWebRequest reqFTP= (FtpWebRequest)FtpWebRequest.Create(serverFile); 
reqFTP.Method = WebRequestMethods.Ftp.Rename; 
reqFTP.Credentials = new NetworkCredential(ftpUser, ftpPass); 
reqFTP.RenameTo = “../Move/FTP.txt"; 

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