Here is my code to upload a file :
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Credentials = new NetworkCredential("****", "*****");
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
reqFTP.KeepAlive = false;
reqFTP.UseBinary = true;
reqFTP.UsePassive = true;
reqFTP.ContentLength = stream.Length;
// reqFTP.EnableSsl = true; // it's FTPES type of ftp
int buffLen = 2048;
byte[] buff = new byte[buffLen];
int contentLen;
try
{
Stream ftpStream = reqFTP.GetRequestStream();
contentLen = stream.Read(buff, 0, buffLen);
while (contentLen != 0)
{
ftpStream.Write(buff, 0, contentLen);
contentLen = stream.Read(buff, 0, buffLen);
}
ftpStream.Flush();
ftpStream.Close();
ftpStream.Dispose();
}
catch (Exception exc)
{
return false;
}
//delete image from local
stream.Flush();
stream.Close();
stream.Dispose();
DeleteFile();
DeleteFile method try to delete the uploaded file; but it has an error that the file is being used by my app and so it can not delete it. Is there any one to help me about this issue?!
UPDATE1 :
private void DeleteFile()
{
DirectoryInfo DirInfo = new DirectoryInfo(#"Direectory Contains uploaded file");
foreach (FileInfo file in DirInfo.GetFiles())
{
file.Delete();
}
}
I assume you want to delete the local file? The error says the file is still in use. Wrap the code where you initalize the stream variable in a using block.
Related
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];
I'm trying to download a directory, using FTP in a C# application. I basically need to take a remote dir, and move it, and its contents into a local dir.
Here is the function I'm currently using, and what the log output and errors are. The sample I'm referencing is for getting files, and possibly not directories:
private void Download(string file, string destination)
{
try
{
string getDir = "ftp://" + ftpServerIP + ftpPath + file + "/";
string putDir = destination + "\\" + file;
Debug.WriteLine("GET: " + getDir);
Debug.WriteLine("PUT: " + putDir);
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create
(new Uri(getDir));
reqFTP.Credentials = new NetworkCredential(ftpUserID,
ftpPassword);
reqFTP.UseBinary = true;
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.Proxy = null;
reqFTP.UsePassive = false;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream writeStream = new FileStream(putDir, FileMode.Create);
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = responseStream.Read(buffer, 0, Length);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = responseStream.Read(buffer, 0, Length);
}
writeStream.Close();
response.Close();
}
catch (WebException wEx)
{
MessageBox.Show(wEx.Message, "Download Error");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Download Error");
}
}
Debug:
GET: ftp://I.P.ADDR/SOME_DIR.com/members/forms/THE_FOLDER_TO_GET/
PUT: C:\Users\Public\Documents\iMacros\Macros\THE_FOLDER_TO_WRITE
A first chance exception of type 'System.Net.WebException' occurred in System.dll
MessageBox Output:
The requested URI is invalid for this FTP command.
The slash on the end of the getDir indicates a directory - can you use mget and pass a path like that ends in "/*"?
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 :)
I get "System.NotSupportedException: The given path's format is not supported. at System.Security.Util.StringExpressionSet" when trying to download an item from an ftp(which have access to). The upload seems to work fine and is done similarly I'll post both functions below:
private void Download(string filePath, string fileName)
{
FtpWebRequest reqFTP;
try
{
//filePath = <<The full path where the file is to be created. the>>,
//fileName = <<Name of the file to be createdNeed not name on FTP server. name name()>>
Label1.Text = filePath + "/" + fileName;
FileStream outputStream = new FileStream(filePath + "/" + fileName, FileMode.Create);
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new
Uri("ftp://" + ftpServerIP + "/" + fileName));
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
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();
}
catch (Exception ex)
{
Label1.Text = ex.ToString();
}
}
public void Upload(string filename)
{
FileInfo fileInf = new FileInfo(filename);
string uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
FtpWebRequest reqFTP;
// Create FtpWebRequest object from the Uri provided
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP +"/" + fileInf.Name));
// Provide the WebPermission Credintials
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
// 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 = 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
contentLen = fs.Read(buff, 0, buffLength);
// Till Stream content ends
while (contentLen != 0)
{
// Write Content from the file stream to the FTP Upload Stream
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
// Close the file stream and the Request Stream
strm.Close();
fs.Close();
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message, "Upload Error");
}
}
and these are the function calls
protected void btnDownload_Click(object sender, EventArgs e)
{
string FullServer = "ftp://" + ftpServerIP;
Download(FullServer, LbxServer.SelectedValue);
}
protected void btnUpload_Click(object sender, EventArgs e)
{
Upload(LbxLocal.SelectedValue);
}
Thank you all for any help on this matter.
I think you'll find that ftp://myservername is an invalid scheme for a new FileStream. Note that your FileStream represents the local target, not the remote file.
If your intent is to download a remote file to your local system, filePath should refer to a folder on your local network (e.g., C:\temp or \\somecomputer\share, etc.)
The following code is good for uploading text files, but it fails to upload JPEG files (not completely - the file name is good but the image is corrupted):
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());
}
}
I have another solution that can upload a file:
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");
}
}
But here I have the opposite problem - the picture is good, but the file name is corrupted.
I know it is because of the encoding, but I don't know how to make the bytes array have the desired encoding...
Try this bit:
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());
}
}
You should be using a Stream to read binary files, not a StreamReader. StreamReader is designed to read text files only.
In your first code example, enable binary transfer: FtpWebRequest.UseBinary = true. Otherwise it will convert what it thinks are textual line endings between the various platform conventions (but are actually part of the image).
Your second snippet does it the right way. It uses FileStream, not StreamReader. StreamReader is only suitable for text files.
System.Text.Encoding.UTF8.GetBytes(stream.ReadToEnd());
Don't do this unless your stream's contents are text. Change your function to accept a boolean parameter "binary", and use the latter, working method if that flag is set.
If you have this problem: The requested FTP command is not supported when using HTTP
you need set proxy in Null or Nothing.
ftpReq.Proxy = null;
You can see this blog.
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
Thanks.