2010-06-14 8 views
8

Bemerkung: Aufgrund der Spam-Abwehr wurde ich gezwungen, den Anfang des Uris von ftp: // auf ftp zu ersetzen.Datei kann nicht mit FTP-Methoden umbenannt werden, wenn das aktuelle Benutzerverzeichnis nicht mit dem root übereinstimmt

Ich habe folgendes Problem. Ich muss Datei mit C# ftp-Methode hochladen und anschließend umbenennen. Einfach richtig? :)

Ok, lassen Sie uns sagen, mein FTP-Host ist wie folgt:

ftp.contoso.com

und nach in, aktuellen Verzeichnis Anmeldung ist eingestellt auf:

users/name

Also, was ich versuche zu zu erreichen ist, sich anzumelden, Datei zum aktuellen Verzeichnis als Datei.ext.tmp hochzuladen und nach erfolgreichem Upload die Datei in Datei.ext umzubenennen

Die ganze Schwierigkeit ist, wie ich denke, die Anfrage Uri für richtig einzustellen FtpWebRe Suche.

MSDN heißt es:

The URI may be relative or absolute. If the URI is of the form " ftp://contoso.com/%2fpath " (%2f is an escaped '/'), then the URI is absolute, and the current directory is /path. If, however, the URI is of the form " ftp://contoso.com/path ", first the .NET Framework logs into the FTP server (using the user name and password set by the Credentials property), then the current directory is set to UserLoginDirectory/path.

Ok, so dass ich lade Datei mit dem folgenden URI:

ftp.contoso.com/file.ext.tmp

Große, die Datei landet, wo ich es sein wollte: im Verzeichnis „Benutzer/name "

Nun möchte ich die Datei umbenennen, so dass ich erstellen mit folgenden Uri Web-Anfrage:

ftp.contoso.com/file.ext.tmp

und angeben umbenennen Parametern:

file.ext

und das gibt mir Fehler 550: Datei nicht gefunden, keine Berechtigungen usw.

ich dies in Microsoft Network Monitor verfolgt und es gab mir:

als ob es nach der Datei im Stammverzeichnis suchen würde - nicht im aktuellen Verzeichnis.

I umbenannt die Datei manuell Total Commander und der einzige Unterschied war, dass unter Verwendung von Commandparameter ohne den ersten Schrägstrich war:

CommandParameter: file.ext.tmp

Ich bin in der Lage, erfolgreich die Datei umbenennen, indem Sie folgende absolute URI Versorgung:

ftp.contoso.com/%2fusers/%2fname/file.ext.tmp

aber ich mag diesen Ansatz nicht, da ich den Namen des aktuellen Benutzerverzeichnisses kennen müsste. Dies kann wahrscheinlich mithilfe von WebRequestMethods.Ftp.PrintWorkingDirectory erfolgen, aber es führt zu zusätzlicher Komplexität (durch Aufrufen dieser Methode zum Abrufen des Verzeichnisnamens und anschließendes Kombinieren der Pfade zum richtigen URI).

Was ich nicht verstehe ist, warum die URI ftp.contoso.com/file.ext.tmp gut zum Hochladen und nicht zum Umbenennen ist? Fehle ich hier etwas?

Das Projekt wird auf .NET 4.0 festgelegt, das in Visual Studio 2010 codiert ist.

bearbeiten

Ok, I-Code-Snippet platzieren.

Bitte beachten Sie, dass FTP-Host, Benutzername und Passwort ausgefüllt werden sollten. Für diese Probe zu arbeiten - das heißt, zu einem Fehler - Benutzerverzeichnis von Root unterschiedlich sein muß ("pwd" -Kommando etwas anderes als "/" zurückgeben soll)

class Program 
{ 
    private const string fileName = "test.ext"; 
    private const string tempFileName = fileName + ".tmp"; 
    private const string ftpHost = "127.0.0.1"; 
    private const string ftpUserName = "anonymous"; 
    private const string ftpPassword = ""; 
    private const int bufferSize = 524288; 

    static void Main(string[] args) 
    { 
     try 
     { 
      string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), fileName); 

      if (!File.Exists(path)) 
       File.WriteAllText(path, "FTP RENAME SAMPLE"); 

      string requestUri = "ftp://" + ftpHost + "/" + tempFileName; 

      //upload 

      FtpWebRequest uploadRequest = (FtpWebRequest)WebRequest.Create(requestUri); 
      uploadRequest.UseBinary = true; 
      uploadRequest.UsePassive = true; 
      uploadRequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword); 
      uploadRequest.KeepAlive = true; 
      uploadRequest.Method = WebRequestMethods.Ftp.UploadFile; 

      Stream requestStream = null; 
      FileStream localFileStream = null; 


      localFileStream = File.OpenRead(path); 
      requestStream = uploadRequest.GetRequestStream(); 
      byte[] buffer = new byte[bufferSize]; 

      int readCount = localFileStream.Read(buffer, 0, bufferSize); 
      long bytesSentCounter = 0; 

      while (readCount > 0) 
      { 
       requestStream.Write(buffer, 0, readCount); 
       bytesSentCounter += readCount; 
       readCount = localFileStream.Read(buffer, 0, bufferSize); 
       System.Threading.Thread.Sleep(100); 
      } 

      localFileStream.Close(); 
      requestStream.Close(); 

      FtpWebResponse response = (FtpWebResponse)uploadRequest.GetResponse(); 
      FtpStatusCode code = response.StatusCode; 
      string description = response.StatusDescription; 
      response.Close(); 

      if (code == FtpStatusCode.ClosingData) 
       Console.WriteLine("File uploaded successfully"); 

      //rename 

      FtpWebRequest renameRequest = (FtpWebRequest)WebRequest.Create(requestUri); 
      renameRequest.UseBinary = true; 
      renameRequest.UsePassive = true; 
      renameRequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword); 
      renameRequest.KeepAlive = true; 
      renameRequest.Method = WebRequestMethods.Ftp.Rename; 
      renameRequest.RenameTo = fileName; 

      try 
      { 

       FtpWebResponse renameResponse = (FtpWebResponse)renameRequest.GetResponse(); 

       Console.WriteLine("Rename OK, status code: {0}, rename status description: {1}", response.StatusCode, response.StatusDescription); 

       renameResponse.Close(); 
      } 
      catch (WebException ex) 
      { 
       Console.WriteLine("Rename failed, status code: {0}, rename status description: {1}", ((FtpWebResponse)ex.Response).StatusCode, 
        ((FtpWebResponse)ex.Response).StatusDescription); 
      } 

     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.ToString()); 
     } 
     finally 
     { 
      Console.ReadKey(); 
     } 
    } 
} 
+1

Sie haben ausführlich über Ihr Problem berichtet (vielleicht zu umfangreich?), Aber was wirklich helfen würde, ist Ihren Code anzuzeigen, insbesondere den Teil, den Sie umbenennen. Beachten Sie, dass Sie normalerweise den Site-Namen bei FTP nicht voranstellen müssen. – Abel

Antwort

4

C#

using System.Net; 
using System.IO; 

Benennen Sie Dateinamen auf dem FTP-Server-Funktion

C#

private void RenameFileName(string currentFilename, string newFilename) 
    { 
     FTPSettings.IP = "DOMAIN NAME"; 
     FTPSettings.UserID = "USER ID"; 
     FTPSettings.Password = "PASSWORD"; 
     FtpWebRequest reqFTP = null; 
     Stream ftpStream = null ; 
     try 
     { 

      reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + FTPSettings.IP + "/" + currentFilename)); 
      reqFTP.Method = WebRequestMethods.Ftp.Rename; 
      reqFTP.RenameTo = newFilename; 
      reqFTP.UseBinary = true; 
      reqFTP.Credentials = new NetworkCredential(FTPSettings.UserID, FTPSettings.Password); 
      FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 
      ftpStream = response.GetResponseStream(); 
      ftpStream.Close(); 
      response.Close(); 
     } 
     catch (Exception ex) 
     { 
      if (ftpStream != null) 
      { 
       ftpStream.Close(); 
       ftpStream.Dispose(); 
      } 
      throw new Exception(ex.Message.ToString()); 
     } 
    } 

    public static class FTPSettings 
    { 
     public static string IP { get; set; } 
     public static string UserID { get; set; } 
     public static string Password { get; set; } 
    } 
7

mir ein ähnliches Problem begegnet ist. Das Problem ist, dass FtpWebRequest (fälschlicherweise) prepends ‚/‘ Anfragen zu benennen, wie aus diesem Protokoll zu sehen (laden & Umbenennungs):

URL: 
    http://127.0.0.1/Test.txt 
FTP log: 
    STOR Test.txt.part 
    RNFR /Test.txt.part 
    RNTO /Test.txt 

Bitte beachten Sie, dass dieses Problem nur auftritt, wenn Sie an die Wurzel hochladen Verzeichnis. Wenn Sie die URL zu http://127.0.0.1/path/Test.txt änderten, würde alles gut funktionieren.

Meine Lösung für dieses Problem ist% 2E (dot) als Pfad zu verwenden:

URL: 
    http://127.0.0.1/%2E/Test.txt 
FTP log: 
STOR ./Test.txt.part 
RNFR ./Test.txt.part 
RNTO ./Test.txt 

Sie haben den Punkt URL-Codierung, sonst FtpWebRequest würde den Weg "/./" vereinfachen "/".

+0

Danke. Dies hat ein ziemlich obskures .NET FTP Problem für mich behoben. Keine andere Lösung hat funktioniert. –

Verwandte Themen