2011-02-01 31 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はlocalhostに解決されています)

このようなディレクトリ間でファイルを移動することは可能でしょうか?それ以外の場合はどうすれば可能ですか?提起されているポイント/提案のいくつかに対処するには

  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をブラウザに接続すると機能しますか? –

+0

パスにエスケープする必要のある特殊文字が含まれていますか? –

+0

最新の編集を参照してください。答えは:はい - ブラウザからは機能しません。また、パスには特殊文字がありません –

答えて

10

MSDNは、パスが相対パスとみなされ、指定された資格情報を使用してFTPサーバーにログインし、現在のディレクトリを<UserLoginDirectory>/pathディレクトリに設定しようとしているようです。これがあなたのファイルと同じディレクトリでない場合は、550エラーが発生します。

+0

最新の編集内容を確認してください。パスに%2fのさまざまな組み合わせを試しましたが、成功しませんでした。 –

+0

私は質問を更新しました。あなたが正しいと思われますが、私が試したことに関係なく絶対的な道筋を得ることはできませんでした。 –

+0

良い見つける。それが私の問題だったなら、おそらく私はこのことを理解するためにしばらく時間がかかりました。 –

0

これらのフォルダはFTPサービスで定義されていますか? FTPサービスは動作していますか?いずれかの質問に対する答えが「いいえ」の場合、FTPを使用してファイルを移動することはできません。

FTPクライアントでFTPフォルダを開き、何が起こるかを確認してください。まだエラーが発生している場合は、FTPサービスにフォルダが表示されないか、FTPサービスにあると思われる場所にフォルダが存在しないため、定義に問題があります。

また、IISマネージャーを開いて、FTPでの設定方法を確認することもできます。

ファイルを移動する他の方法としては、プログラムが実行されているアカウントが両方に対して適切な権限を持っている限り、UNCパスから別のパスに簡単に移動できます。 UNCパスは、HTTPまたはFTPパスに似ています。反対方向の折り返しとプロトコルが指定されていません。

0

コードが正しいように見えます。だからあなたは間違ったパスを持っているか、ファイルDOESNTが存在するか、あるいはケースを尊重する必要があります(明らかにWindowsは大文字小文字を区別しませんが、Linux、Unixはそうです)。

は、ブラウザでファイルを開こうとしましたか? Windowsのファイルエクスプローラを開き、パスバーにアドレスを入力して取得した内容を確認します。

+0

最新の編集内容を見る - ブラウザでファイルが正常に開きます –

1

私はこの作業を取得することができただけで、それがサーバー上に存在するように、パスを使用して、あなただけの絶対パスを持っている場合、すなわち/DRIVELETTER:/FOLDERNAME/filename = "

1

RenameToでは?

[OK]を、私が来ました私は同じエラーが発生していたので、このポストを渡って。答えは絶対パス文字列としてフォルダパスを取得するため、私の問題の解決策としてはあまりよくない相対パスを使用するように思われる。

解決策私はフライ仕事で思いつきましたが、少なくとも言わないと醜いです。私はこれをコミュニティのwiki回答とし、 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サービスを構築してみてくださいあなたのファイルがあるサーバー上で動作します。ファイル名を渡すパラメータでビルドします。あなたは、ファイル名に値を追加したい場合がありますそもそもファイルを書き込むとき、ファイルに相関データのPKは、などと言う

+1

これは答えではなくコメントでなければなりません。 –

+0

@ Jester610、例を挙げて説明してください。 –

1

次のコード例では、私は、次のデータで試してみました、それが動作します。

FTPのログイン場所は、 ":\ FTP C" です。

ファイルを元の場所 "C:FTP \データ\ 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(); 
関連する問題