У меня есть приложение, которое загружает файлы с FTP-сервера Unix. Он работает нормально, просто проблема с этой производительностью: файлы размером < = 1K загружаются в среднем между 2084 и 2400 миллисекундами для скачивания, тогда как приложения, такие как Filezilla, загружают одни и те же файлы менее чем за 1 секунду (за каждый файл).C# ftpwebrequest performance
Возможно, на этот раз это нормально для некоторых обычных пользователей, но неприемлемо для моего приложения, так как мне нужно загрузить THOUSANDS файлов.
Я оптимизирую код столько, сколько мог: - Кэш и буфер для чтения содержимого создаются 1 раз в конструкторе класса. - Я создаю 1 раз учетные данные сети и повторно использую каждую загрузку файла. Я знаю, что это работает, потому что для первого файла он загружается как 7s, а все последующие загрузки находятся в диапазоне от 2s. - Я изменяю размер буфера от 2K до 32K. Я не знаю, поможет ли это или нет, поскольку файлы Im загружаются меньше 1K, поэтому теоретически буфер будет заполняться всей информацией в 1 раунде из сети.
Возможно, это не связано с сетью, но к тому, как Im пишет и/или окна обрабатывает запись файла?
Может кто-нибудь, пожалуйста, дайте мне несколько советов о том, как сократить время на что-то похожее на filezilla ?? Мне нужно сократить время, в противном случае мой ftp будет работать в течение 3 дней 24 часа в сутки, чтобы завершить свою задачу :( Большое спасибо заранее. Код здесь: Его не полный, он просто показывает загружаемую часть.
//Create this on the constructor of my class
downloadCache = new MemoryStream(2097152);
downloadBuffer = new byte[32768];
public bool downloadFile(string pRemote, string pLocal, out long donwloadTime)
{
FtpWebResponse response = null;
Stream responseStream = null;
try
{
Stopwatch fileDownloadTime = new Stopwatch();
donwloadTime = 0;
fileDownloadTime.Start();
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(pRemote);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.UseBinary = false;
request.AuthenticationLevel = AuthenticationLevel.None;
request.EnableSsl = false;
request.Proxy = null;
//I created the credentials 1 time and re-use for every file I need to download
request.Credentials = this.manager.ftpCredentials;
response = (FtpWebResponse)request.GetResponse();
responseStream = response.GetResponseStream();
downloadCache.Seek(0, SeekOrigin.Begin);
int bytesSize = 0;
int cachedSize = 0;
//create always empty file. Need this because WriteCacheToFile just append the file
using (FileStream fileStream = new FileStream(pLocal, FileMode.Create)) { };
// Download the file until the download is completed.
while (true)
{
bytesSize = responseStream.Read(downloadBuffer, 0, downloadBuffer.Length);
if (bytesSize == 0 || 2097152 < cachedSize + bytesSize)
{
WriteCacheToFile(pLocal, cachedSize);
if (bytesSize == 0)
{
break;
}
downloadCache.Seek(0, SeekOrigin.Begin);
cachedSize = 0;
}
downloadCache.Write(downloadBuffer, 0, bytesSize);
cachedSize += bytesSize;
}
fileDownloadTime.Stop();
donwloadTime = fileDownloadTime.ElapsedMilliseconds;
//file downloaded OK
return true;
}
catch (Exception ex)
{
return false;
}
finally
{
if (response != null)
{
response.Close();
}
if (responseStream != null)
{
responseStream.Close();
}
}
}
private void WriteCacheToFile(string downloadPath, int cachedSize)
{
using (FileStream fileStream = new FileStream(downloadPath, FileMode.Append))
{
byte[] cacheContent = new byte[cachedSize];
downloadCache.Seek(0, SeekOrigin.Begin);
downloadCache.Read(cacheContent, 0, cachedSize);
fileStream.Write(cacheContent, 0, cachedSize);
}
}
Я забыл сказать:.. Im, используя несколько потоков для загрузки нескольких файлов одновременно. – user2232787