Не мог переименовать файл с методами ftp, когда текущий пользовательский каталог отличается от корня

Комментарий: из-за механизма предотвращения спама я был вынужден заменить начало Uris от ftp:// до ftp.

У меня есть следующая проблема. Я должен загрузить файл с методом ftp C# и впоследствии переименовать его. Легкий, правильно?:)

Хорошо, скажем, мой хост ftp похож на это:

ftp.contoso.com

и после входа в систему, текущий каталог установлен на:

пользователи/имя

Так, чего я пытаюсь достигнуть, должен войти в систему, файл загрузки к текущему каталогу как file.ext.tmp и после того, как загрузка успешна, переименуйте файл к file.ext

Целая трудность, как я предполагаю, для надлежащей установки Uri запроса для FtpWebRequest.

Состояния MSDN:

URI может быть относительным или абсолютным. Если URI имеет форму "ftp://contoso.com/%2fpath" (%2f, завершенное '/'), то URI является абсолютным, и текущий каталог является путем/. Если, однако, URI имеет форму "ftp://contoso.com/path", сначала Платформа.NET входит в FTP-сервер (использующий имя пользователя и пароль, установленное свойством Credentials), то текущий каталог установлен на UserLoginDirectory/path.

Хорошо, таким образом, я загружаю файл со следующим URI:

ftp.contoso.com/file.ext.tmp

Большой, файл приземляется, где я хотел, чтобы он был: в каталоге "пользователи/имя"

Теперь, я хочу переименовать файл, таким образом, я создаю веб-запрос со следующим Uri:

ftp.contoso.com/file.ext.tmp

и укажите, переименовывают к параметру как:

file.ext

и это дает мне 550 ошибок: файл, не найденный, никакие полномочия, и т.д.

Я проследил это в Microsoft Network Monitor, и она дала мне:

Команда: RNFR, переименуйте от
CommandParameter:/file.ext.tmp
Ftp: Ответ на Порт 53724, '550 Файлов/file.ext.tmp не найденный'

как будто это искало файл в корневом каталоге - не в текущем каталоге.

Я переименовал файл вручную с помощью Общего Командующего, и единственная разница была то, что CommandParameter был без первой наклонной черты:

CommandParameter: file.ext.tmp

Я могу успешно переименовать файл путем предоставления после абсолютного URI:

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

но мне не нравится этот подход, так как я должен был бы знать название каталога текущего пользователя. Это может, вероятно, быть сделано при помощи WebRequestMethods. Ftp. PrintWorkingDirectory, но это добавляет дополнительную сложность (называющий этот метод для получения имени каталога, затем комбинируя пути для формирования надлежащего URI).

То, что я не понимаю, - то, почему ftp.contoso.com/file.ext.tmp URI хорош для загрузки, а не для переименовывают? Я пропускаю что-то здесь?

Проект установлен на.NET 4.0, кодирован в Visual Studio 2010.

Править

Хорошо, я помещаю фрагмент кода.

Обратите внимание на то, что хост ftp, имя пользователя и пароль должны быть заполнены. Чтобы этот образец работал - то есть, произведите ошибку - пользовательский каталог должен отличаться от корня ("pwd" - команда должна возвратить что-то другое, чем "/"),

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();
        }
    }
}

9
задан John Saunders 11 January 2012 в 19:52
поделиться