【问题标题】:Upload a file with encoding using FTP in C#在 C# 中使用 FTP 上传带有编码的文件
【发布时间】:2011-04-04 08:03:51
【问题描述】:

以下代码适合上传文本文件,但上传JPEG文件失败(不完全——文件名好但图片损坏):

private void up(string sourceFile, string targetFile)
{
    try
    {
        string ftpServerIP = ConfigurationManager.AppSettings["ftpIP"];
        string ftpUserID = ConfigurationManager.AppSettings["ftpUser"];
        string ftpPassword = ConfigurationManager.AppSettings["ftpPass"];

        //string ftpURI = "";
        string filename = "ftp://" + ftpServerIP + "//" + targetFile;
        FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(filename);
        ftpReq.Method = WebRequestMethods.Ftp.UploadFile;
        ftpReq.Credentials = new NetworkCredential(ftpUserID, ftpPassword);

        StreamReader stream = new StreamReader(sourceFile);
        Byte[] b = System.Text.Encoding.UTF8.GetBytes(stream.ReadToEnd());
        stream.Close();

        ftpReq.ContentLength = b.Length;
        Stream s = ftpReq.GetRequestStream();
        s.Write(b, 0, b.Length);
        s.Close();

        System.Net.FtpWebResponse ftpResp = (FtpWebResponse)ftpReq.GetResponse();
        MessageBox.Show(ftpResp.StatusDescription);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

我有另一个可以上传文件的解决方案:

private void Upload(string sourceFile, string targetFile)
{
    string ftpUserID;
    string ftpPassword;
    string ftpServerIP;
    ftpServerIP = ConfigurationManager.AppSettings["ftpIP"];
    ftpUserID = ConfigurationManager.AppSettings["ftpUser"];
    ftpPassword = ConfigurationManager.AppSettings["ftpPass"];
    FileInfo fileInf = new FileInfo(sourceFile);
    FtpWebRequest reqFTP;

    // Create FtpWebRequest object from the Uri provided
    reqFTP = (FtpWebRequest)(FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "//" + targetFile)));

    // Provide the WebPermission Credintials
    reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);

    // Bypass default lan settings
    reqFTP.Proxy = null;

    // By default KeepAlive is true, where the control connection is not closed
    // after a command is executed.
    reqFTP.KeepAlive = false;

    // Specify the command to be executed.
    reqFTP.Method = WebRequestMethods.Ftp.UploadFile;

    // Specify the data transfer type.
    reqFTP.UseBinary = true;

    // Notify the server about the size of the uploaded file
    reqFTP.ContentLength = fileInf.Length;

    // The buffer size is set to 2kb
    int buffLength = 2048;
    Byte[] buff;
    buff = new byte[buffLength];
    int contentLen;

    // Opens a file stream (System.IO.FileStream) to read the file to be uploaded
    FileStream fs = fileInf.OpenRead();

    try
    {
        // Stream to which the file to be upload is written
        Stream strm = reqFTP.GetRequestStream();

        // Read from the file stream 2kb at a time
        long filesize = fs.Length;
        int i=0;
        contentLen = fs.Read(buff, 0, buffLength);

        // Till Stream content ends
        while (contentLen != 0)
        {
            Application.DoEvents();
            // Write Content from the file stream to the FTP Upload Stream
            strm.Write(buff, 0, contentLen);
            contentLen = fs.Read(buff, 0, buffLength);
            i = i + 1;
            //Double percentComp = (i * buffLength) * 100 / filesize;
            //ProgressBar1.Value = (int)percentComp;
        }

        // Close the file stream and the Request Stream
        strm.Close();
        fs.Close();
    }

    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Upload Error");
    }
}

但是这里我有相反的问题——图片很好,但是文件名损坏了。

我知道这是因为编码,但我不知道如何使字节数组具有所需的编码...

【问题讨论】:

  • 我无法理解,为什么第二个代码会出现文件名损坏的问题,而第一个代码却没有。以及为什么接受的答案会对此有所帮助。在所有情况下,您都以完全相同的方式指定文件名。
  • 对不起马丁。我十年前写了这个问题。我不记得是什么问题以及解决方案是什么。我认为你应该用你自己的问题打开一个新线程。
  • 我没有问题,我只是想知道你的问题和答案有什么意义:)
  • :) ...我的过去正在追捕我 ;)...我真的不记得了。很可能是我做错了什么(错误),甚至可能微软现在已经修复了一个错误......

标签: c# encoding ftp filestream


【解决方案1】:

试试这个:

private static void up(string sourceFile, string targetFile)
{            
    try
    {
        string ftpServerIP = ConfigurationManager.AppSettings["ftpIP"];
        string ftpUserID = ConfigurationManager.AppSettings["ftpUser"];
        string ftpPassword = ConfigurationManager.AppSettings["ftpPass"];
        ////string ftpURI = "";
        string filename = "ftp://" + ftpServerIP + "//" + targetFile; 
        FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(filename);
        ftpReq.UseBinary = true;
        ftpReq.Method = WebRequestMethods.Ftp.UploadFile;
        ftpReq.Credentials = new NetworkCredential(ftpUserID, ftpPassword);

        byte[] b = File.ReadAllBytes(sourceFile);

        ftpReq.ContentLength = b.Length;
        using (Stream s = ftpReq.GetRequestStream())
        {
            s.Write(b, 0, b.Length);
        }

        FtpWebResponse ftpResp = (FtpWebResponse)ftpReq.GetResponse();

        if (ftpResp != null)
        {
            MessageBox.Show(ftpResp.StatusDescription);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

【讨论】:

  • 为什么s.Write(b, 0, b.Length);using 块内?
  • 因为Stream sIDisposable 资源。
  • 在这里,神奇的区别也在于byte[] b = File.ReadAllBytes(sourceFile); 与找到的其他示例又名Encoding.UTF8.GetBytes(stream.ReadToEnd()) 相比。
【解决方案2】:

您应该使用Stream 来读取二进制文件,而不是StreamReaderStreamReader 仅用于读取文本文件。

【讨论】:

  • 我现在尝试了 3 个小时的代码,并且我还找到了编码附带的 streamReader(在构造函数中) - 但我不明白如何不使用流读取器或流对象.流对我来说就像一个黑盒子:(
【解决方案3】:

在您的第一个代码示例中,启用二进制传输:FtpWebRequest.UseBinary = true。否则它将在各种平台约定之间转换它认为的文本行尾(但实际上是图像的一部分)。

【讨论】:

  • 肯定还有什么遗漏...我添加了你玩我的那句——但没有任何改变。
  • 是的,请参阅 Mark 的回答:您正在尝试将文件作为 UTF8 文本读取。抛弃 StreamReader 并直接从流中读取字节,例如与 Stream.Read().
【解决方案4】:

您的第二个 sn-p 以正确的方式执行此操作。它使用 FileStream,而不是 StreamReader。 StreamReader 只适用于文本文件。

【讨论】:

    【解决方案5】:

    System.Text.Encoding.UTF8.GetBytes(stream.ReadToEnd());

    除非您的流的内容是文本,否则不要这样做。更改您的函数以接受布尔参数“二进制”,如果设置了该标志,则使用后者的工作方法。

    【讨论】:

      【解决方案6】:

      如果你有这个问题:使用 HTTP 时不支持请求的 FTP 命令

      您需要在 Null 或 Nothing 中设置代理。

      ftpReq.Proxy = null;
      

      你可以看到这个博客。

      http://mycodetrip.com/2008/10/29/fix-for-error-the-requested-ftp-command-is-not-supported-when-using-http-proxy_118/comment-page-1/#comment-2825

      谢谢。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-08-14
        • 1970-01-01
        • 2013-02-22
        • 2020-07-12
        • 2014-12-24
        相关资源
        最近更新 更多