【问题标题】:Download a file with name including special characters from FTP server in C#从 C# 中的 FTP 服务器下载名称包含特殊字符的文件
【发布时间】:2013-07-23 14:33:12
【问题描述】:

我尝试下载文件,但无法识别所有带有特殊字符的文件。可以下载其他文件,但不能下载名为asdf#code@.pdf 的文件。

错误:

远程服务器返回错误:(550) 文件不可用(例如,找不到文件,无法访问)。

在本地,创建了正确名称的文件,但它是空的。同样的事情发生在文件名中带有# 的JPG 文件上。我怎样才能让他们被认出来?

//Download the file from remote path on FTP to local path
private static void Download(string remotePath, string localPath)
{
    FtpWebRequest reqFTP;
    try
    {
        reqFTP = GetWebRequest(WebRequestMethods.Ftp.DownloadFile, remotePath);
        FileStream outputStream = new FileStream(localPath, FileMode.Create);

        FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
        Stream ftpStream = response.GetResponseStream();
        long cl = response.ContentLength;
        int bufferSize = 2048;
        int readCount;
        byte[] buffer = new byte[bufferSize];
        readCount = ftpStream.Read(buffer, 0, bufferSize);
        while (readCount > 0)
        {
            outputStream.Write(buffer, 0, readCount);
            readCount = ftpStream.Read(buffer, 0, bufferSize);
        }
        ftpStream.Close();
        outputStream.Close();
        response.Close();
        Console.WriteLine("File Download: ", remotePath + " is downloaded completely");
        logWriter.WriteLog("File Download: ", remotePath + " is downloaded completely, status " + response.StatusDescription);
    }
    catch (Exception ex)
    {
        logWriter.WriteLog("File Download: ", "Cannot download file from " + remotePath + " to " + localPath + "\n" + " Erro Message: " + ex.Message);
    }
}//End Download

//Web request for FTP
static public FtpWebRequest GetWebRequest(string method, string uri)
{
    Uri serverUri = new Uri(uri);

    if (serverUri.Scheme != Uri.UriSchemeFtp)
    {
        return null;
    }
    try
    {
        var reqFTP = (FtpWebRequest)FtpWebRequest.Create(serverUri);
        reqFTP.Method = method;
        reqFTP.UseBinary = true;
        reqFTP.Credentials = new NetworkCredential(userId, password);
        reqFTP.Proxy = null;
        reqFTP.KeepAlive = false;
        reqFTP.UsePassive = false;
        return reqFTP;
    }
    catch(Exception ex)
    {
        logWriter.WriteLog("Get Web Request: ","Cannot connect to " + uri + "\n" + "Error: " + ex.Message);
        return null;
    }
}

【问题讨论】:

  • “无法识别”是什么意思?你得到什么错误?当您尝试使用 WebMethods.Ftp.ListDirectory 获取该 FTP 目录的目录列表时,输出是什么?
  • 可以下载其他文件,但不能下载名为“asdf#code@.pdf”的文件。错误:远程服务器返回错误:(550)文件不可用(例如,找不到文件,无法访问)。
  • WebMethods.Ftp.ListDirectory 中的文件名正确。
  • @Quentin:您收到网络服务器抛出的错误。它与此代码无关。如果你拥有这个网络服务器,那么你应该开始研究它。我不知道不同文件系统的命名限制是什么,但我怀疑问题是服务器运行的文件系统和/或代码运行的文件系统不支持名称中包含这些字符的文件。
  • @caesay:我在我的公司尝试了 ftp 服务器(作为测试),在来宾公司尝试了一个。两者都不能下载带有“#”“@”的文件。我应该从客人公司下载文件。我该如何解决?谢谢。

标签: c# .net character-encoding ftp ftpwebrequest


【解决方案1】:

这可能是设计使然:根据the URI standard,# 不是 URI 中的有效字符。因此,ftp://someServer/somePath/intro_to_c#.pdf 不是一个有效的 URI。

您可以做的是在创建 URI 时正确转义文件名:

string baseUri = "ftp://someServer/somePath/";
string file = "intro_to_c#.pdf";
string myUri = baseUri + HttpUtility.UrlEncode(file);
// yields ftp://someServer/somePath/intro_to_c%23.pdf

或者,您可以使用 UriBuilder 类,它可以正确处理转义:

Uri myUri = new UriBuilder("ftp", "someServer", 21, "somePath/intro_to_c#.pdf");
// yields ftp://someServer:21/somePath/intro_to_c%23.pdf

【讨论】:

    【解决方案2】:

    我添加了一些代码并修复了它。使用 hexEscape 转义“#”,但它并不像样。有谁知道转义 URI 中的特殊字符?

        // Get the request using a specific URI 
        static public FtpWebRequest GetWebRequest(string method, string uri)
        {
            Uri serverUri = new Uri(uri);
    
            **if (serverUri.ToString().Contains("#"))
            {
                serverUri = new Uri(serverUri.ToString().Replace("#", Uri.HexEscape('#')));
            }**
            Console.WriteLine(serverUri.ToString());
            if (serverUri.Scheme != Uri.UriSchemeFtp)
            {
                return null;
            }
            try
            {
                var reqFTP = (FtpWebRequest)FtpWebRequest.Create(serverUri);
                reqFTP.Method = method;
                reqFTP.UseBinary = true;
                reqFTP.Credentials = new NetworkCredential(userId, password);
                reqFTP.Proxy = null;
                reqFTP.KeepAlive = false;
                reqFTP.UsePassive = false;
                return reqFTP;
            }
    
            catch (Exception ex)
            {
                logWriter.WriteLog("Get Web Request: ", "Cannot connect to " + uri + "\n" + "Error: " + ex.Message);
                return null;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2021-02-21
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      • 2013-06-30
      • 2021-09-22
      • 2018-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多