I am upload large tar files about 10GB to the ftp server. It is taking a lot of time and throws the following error: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.
I have referred to the following:
C# : FTP upload buffer size
Why is my ftp upload method so slow?
https://www.codeproject.com/Questions/204070/how-to-write-c-code-to-increase-the-ftp-file-uploa
The following is the code:
FileStream fs = null;
Stream rs = null;
try
{
string file = args[0].Replace("---"," ");
string ftpServer = args[1].ToString();
string uploadFileName = new FileInfo(file).Name;
string uploadUrl = ftpServer;
Console.WriteLine("Start Time: {0}", DateTime.Now);
Console.WriteLine("File Name: {0}",file);
fs = new FileStream(file, FileMode.Open, FileAccess.Read);
string ftpUrl = string.Format("{0}/{1}", uploadUrl, uploadFileName);
FtpWebRequest requestObj = FtpWebRequest.Create(ftpUrl) as FtpWebRequest;
requestObj.Timeout = -1; // <---- -1 is Infinite
requestObj.Method = WebRequestMethods.Ftp.UploadFile;
rs = requestObj.GetRequestStream();
byte[] buffer = new byte[4096];
//byte[] buffer = new byte[16000]; // <--- 16k
int read = 0;
while ((read = fs.Read(buffer, 0, buffer.Length)) != 0)
{
rs.Write(buffer, 0, read);
}
rs.Flush();
}
catch (Exception ex)
{
Console.WriteLine("File upload/transfer Failed.\r\nError Message:\r\n" + ex.Message);
}
finally
{
if (fs != null)
{
fs.Close();
fs.Dispose();
}
if (rs != null)
{
rs.Close();
rs.Dispose();
}
}
Console.WriteLine("End Time: {0}", DateTime.Now);
Console.WriteLine("Exiting the application.. press any key to continue");
Console.ReadLine();
UPDATE: I am uploading the file to FTP DropBox and No access to the logs. While trying to upload via clients like FileZilla the speed is faster. The limit of the dropbox is 300 GB. Is it possible to find the rate of transfer?
Please explain the solution as well for my understanding as I am a beginner.
Thanks in advance.
Related
This is the method:
In this case i also use a f.TargetFolder the f.TargetFolder contain: ftpmytestdir
And the variable UploadPath contain:
ftp.newsxpressmedia.com/ftpmytestdir/clean_radar_image.png
Then it will do this line:
UploadPath = "ftp://" + UploadPath;
After that UploadPath will be:
ftp://ftp.newsxpressmedia.com/ftpmytestdir/clean_radar_image.png
files is string[] type
For example in txf i have test.png
I saw the file size and everything there were no exceptions untill the Stream.
I used a breakpoint and moved untill line 78:
using (Stream requestStream = request.GetRequestStream())
On this line it jumped to the catch area and show the exception.
private void StringArrayUploadFiles(object sender, DoWorkEventArgs e)
{
try
{
foreach (string txf in files)
{
string fn = txf;
BackgroundWorker bw = sender as BackgroundWorker;
f = e.Argument as FtpSettings;
string UploadPath = String.Format("{0}/{1}{2}", f.Host, f.TargetFolder == "" ? "" : f.TargetFolder + "/", Path.GetFileName(fn));
if (!UploadPath.ToLower().StartsWith("ftp://"))
UploadPath = "ftp://" + UploadPath;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(UploadPath);
request.UseBinary = true;
request.UsePassive = f.Passive;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Timeout = 300000;
request.Credentials = new NetworkCredential(f.Username, f.Password);
long FileSize = new FileInfo(fn).Length;).Length;
string FileSizeDescription = GetFileSize(FileSize);
int ChunkSize = 4096, NumRetries = 0, MaxRetries = 50;
long SentBytes = 0;
byte[] Buffer = new byte[ChunkSize];
using (Stream requestStream = request.GetRequestStream())
{
using (FileStream fs = File.Open(fn, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
int BytesRead = fs.Read(Buffer, 0, ChunkSize);
while (BytesRead > 0)
{
try
{
if (bw.CancellationPending)
return;
requestStream.Write(Buffer, 0, BytesRead);
SentBytes += BytesRead;
string SummaryText = String.Format("Transferred {0} / {1}", GetFileSize(SentBytes), FileSizeDescription);
bw.ReportProgress((int)(((decimal)SentBytes / (decimal)FileSize) * 100), SummaryText);
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.ToString());
if (NumRetries++ < MaxRetries)
{
fs.Position -= BytesRead;
}
else
{
throw new Exception(String.Format("Error occurred during upload, too many retries. \n{0}", ex.ToString()));
}
}
BytesRead = fs.Read(Buffer, 0, ChunkSize);
}
}
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
System.Diagnostics.Debug.WriteLine(String.Format("Upload File Complete, status {0}", response.StatusDescription));
}
}
catch (WebException ex)
{
switch (ex.Status)
{
case WebExceptionStatus.NameResolutionFailure:
ConnectionError = "Error: Please check the ftp address";
break;
case WebExceptionStatus.Timeout:
ConnectionError = "Error: Timout Request";
break;
}
}
}
This is the exception message: The remote server returned an error: (550) File unavailable (e.g., file not found, no access).
System.Net.WebException was caught
HResult=-2146233079
Message=The remote server returned an error: (550) File unavailable (e.g., file not found, no access).
Source=System
StackTrace:
at System.Net.FtpWebRequest.CheckError()
at System.Net.FtpWebRequest.SyncRequestCallback(Object obj)
at System.IO.Stream.Close()
at System.Net.ConnectionPool.Destroy(PooledStream pooledStream)
at System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)
at System.Net.FtpWebRequest.FinishRequestStage(RequestStage stage)
at System.Net.FtpWebRequest.GetRequestStream()
at FTP_ProgressBar.FtpProgress.StringArrayUploadFiles(Object sender, DoWorkEventArgs e) in c:\ftp_progressbar\FTP_ProgressBar\FtpProgress.cs:line 78
InnerException:
Seems pretty clear from the exception--(550) File unavailable (e.g., file not found, no access).
550 is an FTP error code indicating that the file is unavailable. FTP isn't sophisticated enough to give more details than that.
Since I don't have access to the FTP server or the credentials used, and given that you are trying to upload a file, not download, I'm guessing that the account you're using doesn't have write rights on the server, so you can't create the file. It's also possible that the filename is invalid for some reason.
A good test in situations like this is to use the same credentials to perform the same operation using a 3rd party interactive FTP program.
In my code I want to upload and download a specific JSON-File to a FTP-Server.
The serializing works great and also the upload. When i look up the file via - for example - FileZilla, the content of the file is correct. (on the server)
But when i download this file with my application (and with my code - NOT with FileZilla), I don't get any exceptions, but the file is nearly empty. This is the only content:
{}
And here is my code for downloading:
string ResponseDescription = "";
FtpWebRequest req = (FtpWebRequest)FtpWebRequest.Create("ftp://" + "ftp.strato.com" + "/" + verzeichnis + "/" + file.Name);
req.Method = WebRequestMethods.Ftp.DownloadFile;
req.Credentials = new NetworkCredential(this.benutzer, this.passwort);
req.UseBinary = true;
req.UsePassive = false;
req.Proxy = null;
try
{
FtpWebResponse response = (FtpWebResponse)req.GetResponse();
Stream stream = response.GetResponseStream();
byte[] buffer = new byte[2048];
FileStream fs = new FileStream(destinationFolder + #"/" + destinationFile.Name, FileMode.Create);
int ReadCount = stream.Read(buffer, 0, buffer.Length);
while (ReadCount > 0)
{
fs.Write(buffer, 0, ReadCount);
ReadCount = stream.Read(buffer, 0, buffer.Length);
}
ResponseDescription = response.StatusDescription;
fs.Close();
stream.Close();
return true;
}
catch (Exception e)
{
MessageBox.Show(e.Message); // TODO - better Errorhandling
return false;
}
I found the solution. It was my mistake. The problem wasnt the download - the code was correct (as you said).
After downloading the file the JSON-Deserialization runs and here was the cause. I had a little mistake in my deserialization-logic.
I'm uploading large files to ftp site using this code.
Code
using (FileStream fs = new FileStream(FileLoc, FileMode.Open, FileAccess.Read))
{
string ftpUrl = string.Format("{0}/{1}", uploadUrl, uploadFileName);
FtpWebRequest requestObj = FtpWebRequest.Create(ftpUrl) as FtpWebRequest;
requestObj.Method = WebRequestMethods.Ftp.UploadFile;
requestObj.Credentials = new NetworkCredential(Uid, Pass);
using (Stream requestStream = requestObj.GetRequestStream())
{
byte[] buffer = new byte[8092];
int read = 0;
while ((read = fs.Read(buffer, 0, buffer.Length)) != 0)
{
requestStream.Write(buffer, 0, read);
}
requestStream.Flush();
if (fs != null)
{
fs.Close();
fs.Dispose();
}
if (requestStream != null)
{
requestStream.Close();
requestStream.Dispose();
}
}
}
Some times this code up-lode files very fine but some time it up-lodes some part of file not complete file and doesn't give any error.
Can any one help me why some time it upload only some part of file not hole file.
Here's the code we use for uploading to FTP. It looks very similar to your own. Nevertheleess, I post it for your reference as we haven't had any such reported failures
private void UploadFile(string fileToUpload)
{
Output = new Uri(Path.Combine(Output.ToString(), Path.GetFileName(fileToUpload)));
FtpWebRequest request = WebRequest.Create(Output) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.UploadFile;
// in order to work with Microsoft Windows Server 2003 + IIS, we can't use passive mode.
request.UsePassive = false;
request.Credentials = new NetworkCredential(username, password);
// Copy the contents of the file to the request stream.
Stream dest = request.GetRequestStream();
FileStream src = File.OpenRead(fileToUpload);
int bufSize = (int)Math.Min(src.Length, 1024);
byte[] buffer = new byte[bufSize];
int bytesRead = 0;
int numBuffersUploaded = 0;
do
{
bytesRead = src.Read(buffer, 0, bufSize);
dest.Write(buffer, 0, bufSize);
numBuffersUploaded++;
}
while (bytesRead != 0);
dest.Close();
src.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
if (response.StatusCode != FtpStatusCode.ClosingData)
{
Console.Error.WriteLine("Request {0}: Error uploading file to FTP server: {1} ({2})", Id, response.StatusDescription, response.StatusCode);
}
else
{
Console.Out.WriteLine("Request {0}: Successfully transferred file to {1}", Id, Output.ToString());
}
}
I am developing an windows application for backup(Files and sql server database).
Now i need to upload these files(.rar files) to my ftp site.
For uploading i use this code.
Code
string file = "D:\\RP-3160-driver.zip";
//opening the file for read.
string uploadFileName = "", uploadUrl = "";
uploadFileName = new FileInfo(file).Name;
uploadUrl = "ftp://ftp.Sitename.com/tempFiles/";
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
try
{
long FileSize = new FileInfo(file).Length; // File size of file being uploaded.
Byte[] buffer = new Byte[FileSize];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
fs = null;
string ftpUrl = string.Format("{0}/{1}", uploadUrl, uploadFileName);
FtpWebRequest requestObj = FtpWebRequest.Create(ftpUrl) as FtpWebRequest;
requestObj.Method = WebRequestMethods.Ftp.UploadFile;
requestObj.Credentials = new NetworkCredential("usernam", "password");
Stream requestStream = requestObj.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Flush();
requestStream.Close();
requestObj = null;
MessageBox.Show("File upload/transfer Successed.", "Successed", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
if (fs != null)
{
fs.Close();
}
MessageBox.Show("File upload/transfer Failed.\r\nError Message:\r\n" + ex.Message, "Successed", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
This code uploads only those files which has size < 5 Mb.
But i need to upload larger then 500Mb to 1Gb files.
So can any one help me.
For larger files you may choose to read the file stream and write it to the output stream as you read it.
FileStream fs = null;
Stream rs = null;
try
{
string file = "D:\\RP-3160-driver.zip";
string uploadFileName = new FileInfo(file).Name;
string uploadUrl = "ftp://ftp.Sitename.com/tempFiles/";
fs = new FileStream(file, FileMode.Open, FileAccess.Read);
string ftpUrl = string.Format("{0}/{1}", uploadUrl, uploadFileName);
FtpWebRequest requestObj = FtpWebRequest.Create(ftpUrl) as FtpWebRequest;
requestObj.Method = WebRequestMethods.Ftp.UploadFile;
requestObj.Credentials = new NetworkCredential("usernam", "password");
rs = requestObj.GetRequestStream();
byte[] buffer = new byte[8092];
int read = 0;
while ((read = fs.Read(buffer, 0, buffer.Length)) != 0)
{
rs.Write(buffer, 0, read);
}
rs.Flush();
}
catch (Exception exception)
{
MessageBox.Show("File upload/transfer Failed.\r\nError Message:\r\n" + exception.Message, "Succeeded", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
finally
{
if (fs != null)
{
fs.Close();
fs.Dispose();
}
if (rs != null)
{
rs.Close();
rs.Dispose();
}
}
Stream class has a nice Method CopyTo.
You don't need to read and write from/to streams. Just use fs.CopyTo(requestStream);
With this method, you don't have to declare large arrays like new Byte[FileSize];
First time poster, long-time reader. I have a really annoying problem thats been getting on my nerves. Ive got a program set up so I listen for new files on an FTP server, if theres a new file I download it. From there I work on some of the information in the file, etc. My problem comes when I run through my sequence the second time. That is, on the first file I download everything is totally fine, but as soon as a new file gets detected and my program tries downloading it, my program just hangs.
private static void DownloadFile(string s)
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://blabla.com/"+s);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential("xxx" ,"zzz");
using (FtpWebResponse partResponse = (FtpWebResponse)request.GetResponse())
{
Stream partReader = partResponse.GetResponseStream();
byte[] buffer = new byte[1024];
FileInfo fi = new FileInfo(path);
FileStream memStream = fi.Create();
while (true)
{
int bytesRead = partReader.Read(buffer, 0, buffer.Length - 1);
if (bytesRead == 0)
break;
memStream.Write(buffer, 0, bytesRead);
}
partResponse.Close();
memStream.Close();
}
Console.WriteLine(DateTime.Now + " file downloaded");
MoveFileToInProgress(s);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
The line it hangs on is this one:
using (FtpWebResponse partResponse = (FtpWebResponse)request.GetResponse())
The reason my method here is static is because Im just running it in a different project to test it.. My question here is, how come it only ever dies on the second file? Ive been staring myself blind for hours now!
I ran into this problem as well... try finishing your request first and then closing it before trying to retrieve the response. That worked for me (actually tried it after reading comment by MartinNielsen). Here is what I did.
// connect to the ftp site
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(ftpUri);
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.Credentials = new NetworkCredential(ftpUser, ftpPassword);
// setting proxy to null so that it does not go through the proxy
ftpRequest.Proxy = null;
// get file information
StreamReader fileStream = new StreamReader(filePath);
byte[] fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd());
ftpRequest.ContentLength = fileBytes.Length;
fileStream.Close();
// open connection to ftp site
Stream ftpRequestStream = ftpRequest.GetRequestStream();
// write the file to the stream
ftpRequestStream.Write(fileBytes, 0, fileBytes.Length);
// close the stream
ftpRequestStream.Close();
// get the response from the server
FtpWebResponse ftpUploadResponse = (FtpWebResponse)ftpRequest.GetResponse();
string result = ftpUploadResponse.StatusDescription;
// close response
ftpUploadResponse.Close();
// return response to calling code
return result;
Here are a couple of the resources that I used when writing this code (won't let me post more than 2, there were more)
How to: Upload Files with FTP
Uploading a file -- "The requested URI is invalid for this FTP command"
I'm not expert on C# but I use this code to download files from my ftp:
public void Download(string filename)
{
// I try to download five times before crash
for (int i = 1; i < 5; i++)
{
try
{
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(Global.Path + "/" + filename);
ftp.Credentials = new NetworkCredential(User, Pass);
ftp.KeepAlive = false;
ftp.Method = WebRequestMethods.Ftp.DownloadFile;
ftp.UseBinary = true;
ftp.Proxy = null;
int buffLength = 2048;
byte[] buff = new byte[buffLength];
int contentLen;
string LocalDirectory = Application.StartupPath.ToString() + "/downloads/" + filename;
using (FileStream fs = new FileStream(LocalDirectory, FileMode.Create, FileAccess.Write, FileShare.None))
using (Stream strm = ftp.GetResponse().GetResponseStream())
{
contentLen = strm.Read(buff, 0, buffLength);
while (contentLen != 0)
{
fs.Write(buff, 0, contentLen);
contentLen = strm.Read(buff, 0, buffLength);
}
}
Process.Start(LocalDirectory);
break;
}
catch (Exception exc)
{
if (i == 5)
{
MessageBox.Show("Can't download, try number: " + i + "/5 \n\n Error: " + exc.Message,
"Problem downloading the file");
}
}
}
}
Tell me if it works for you :)