How can I use FTP to move files between directorie

2019-01-14 02:30发布

I have a program that needs to move a file from one directory to another on an FTP server. For example, the file is in:

ftp://1.1.1.1/MAIN/Dir1

and I need to move the file to:

ftp://1.1.1.1/MAIN/Dir2

I found a couple of articles recommending use of the Rename command, so I tried the following:

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

But this doesn’t seem to work – I get the following error:

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

At first I thought this might relate to permissions, but as far as I can see, I have permissions to the entire FTP site (it is on my local PC and the uri is resolved to localhost).

Should it be possible to move files between directories like this, and if not, how is it possible?

To address some of the point / suggestions that have been raised:

  1. I can download the same file from the source directory, so it definitely exists (what I'm doing is downloading the file first, and then moving it somewhere else).
  2. I can access the ftp site from a browser (both the source and target directory)
  3. The ftp server is running under my own IIS instance on my local machine.
  4. The path and case are correct and there are no special characters.

Additionally, I have tried setting the directory path to be:

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

Both for the source and target path - but this makes no difference either.

I found this article, which seems to say that specifying the destination as a relative path would help - it doesn't appear to be possible to specify an absolute path as the destination.

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

9条回答
Fickle 薄情
2楼-- · 2019-01-14 03:13

The code looks correct. So either you have the wrong path, the file DOESNT exist or you need to respect case (obviously Windows is not case sensitive, but Linux, Unix are).

Did you try to open the file in a browser? Open Windows File Explorer and type the address in the path bar and see what you get.

查看更多
Fickle 薄情
3楼-- · 2019-01-14 03:14

In following code example I tried with following data and it works.

FTP Login location is "C:\FTP".

File original location "C:\FTP\Data\FTP.txt".

File to be moved, "C:\FTP\Move\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();
查看更多
霸刀☆藐视天下
4楼-- · 2019-01-14 03:15

I am working on the identical type of project, try building a web service that can move the files around and runs on the server where your files are. Build it with a parameter to pass in the file name. When writing the file to begin with you might want to append a value to the file name, say the PK of the data that correlates to the file etc.

查看更多
smile是对你的礼貌
5楼-- · 2019-01-14 03:16

Had the same problem and found another way to solve the problem:

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; 

    }
查看更多
甜甜的少女心
6楼-- · 2019-01-14 03:18

I was able to get this working but only by using the path as it exists on the server, ie /DRIVELETTER:/FOLDERNAME/filename in RenameTo = "

查看更多
我欲成王,谁敢阻挡
7楼-- · 2019-01-14 03:20

MSDN seems to suggest that your path is considered relative, and therefore it tries to log in to the FTP server using the supplied credentials, then sets the current directory to the <UserLoginDirectory>/path directory. If this isn't the same directory where your file is, you'll get a 550 error.

查看更多
登录 后发表回答