Загрузите файл с кодировкой, используя FTP в С#
Следующий код хорош для загрузки текстовых файлов, но он не может загружать файлы 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");
}
}
Но здесь у меня противоположная проблема - картина хорошая, но имя файла повреждено.
Я знаю, что это из-за кодирования, но я не знаю, как сделать массив байтов нужной кодировкой...
Ответы
Ответ 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());
}
}
Ответ 2
Вы должны использовать Stream
для чтения двоичных файлов, а не StreamReader
. StreamReader
предназначен только для чтения текстовых файлов.
Ответ 3
В первом примере кода включите двоичный перенос: FtpWebRequest.UseBinary = true
. В противном случае он преобразует то, что он считает текстовыми окончаниями строк между различными соглашениями платформы (но на самом деле является частью изображения).
Ответ 4
Ваш второй фрагмент делает это правильно. Он использует FileStream, а не StreamReader. StreamReader подходит только для текстовых файлов.
Ответ 5
System.Text.Encoding.UTF8.GetBytes(stream.ReadToEnd());
Не делайте этого, если содержимое потока не является текстом. Измените свою функцию, чтобы принять логический параметр "двоичный", и используйте последний, рабочий метод, если этот флаг установлен.
Ответ 6
Если у вас есть эта проблема: Запрошенная команда FTP не поддерживается при использовании HTTP
вам нужно установить прокси в 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
Спасибо.