I'm working on an ftp application in c# in which I have to download a file and upload the same file. here is my code for download data.
try
{
textBox1.Text = ftpServerIP;
textBox2.Text = ftpUserID;
textBox3.Text = ftpPassword;
FtpWebRequest reqFTP;
//filePath = <<The full path where the file is to be created.>>,
//fileName = <<Name of the file to be created(Need not be the name of the file on FTP server).>>
FileStream outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);
Uri downloadPath = new Uri("ftp://" + ftpServerIP + "/" + client_fileName);
reqFTP = (FtpWebRequest)FtpWebRequest.Create(downloadPath);
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();
DataBaseOperations db = new DataBaseOperations();
templist = db.GetData();
dataGridView1.DataSource = templist;
dataGridView1.Refresh();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
and my uploading function is
public void Upload(string filename, string url)
{
FileInfo fileInf = new FileInfo(filename+"\\test.s3db");
string uri = "ftp://" + url + "/" +"/public_html/RemoteDic/" + " test.s3db";
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
reqFTP.UseBinary = true;
reqFTP.ContentLength = fileInf.Length;
FileStream inputStream = fileInf.OpenRead();
using (var outputStream = reqFTP.GetRequestStream())
{
var buffer = new byte[1024];
int totalReadBytesCount = 0;
int readBytesCount;
while ((readBytesCount = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
outputStream.Write(buffer, 0, readBytesCount);
totalReadBytesCount += readBytesCount;
var progress = totalReadBytesCount * 100.0 / inputStream.Length;
}
outputStream.Close();
}
inputStream.Close();
}
When I run the program I get an error
The process cannot access the file 'E:\rafay zia mir\web connect\web connect\bin\Debug\test.s3db' because it is being used by another process.
But in the downloading section all streams are closed after the file has been downloaded.
Related
I want to upload image by using ftp account. My code is like this. But when I choose image and submit, It says me "Could not find file 'C:\Program Files (x86)\IIS Express\picture.jpg'." I know my image is on my desktop and I choose from there. If I copy my image manually this IIS folder, it will upload but this is not sensible. I must choose my image where I want. But it is looking for in IIS Express folder.
[HttpPost, ValidateInput(false)]
public ActionResult Insert(Press model, HttpPostedFileBase uploadfile)
{
...........
...........
...........
...........
if (uploadfile.ContentLength > 0)
{
string fileName = Path.Combine(uploadfile.FileName);
var fileInf = new FileInfo(fileName);
var reqFtp =
(FtpWebRequest)
FtpWebRequest.Create(
new Uri("ftp://ftp.adres.com" + fileInf.Name));
reqFtp.Credentials = new NetworkCredential(username, password);
reqFtp.KeepAlive = false;
reqFtp.Method = WebRequestMethods.Ftp.UploadFile;
reqFtp.UseBinary = true;
reqFtp.ContentLength = uploadfile.ContentLength;
int bufferlength = 2048;
byte[] buff = new byte[bufferlength];
int contentLen;
FileStream fs = fileInf.OpenRead();
try
{
Stream strm = reqFtp.GetRequestStream();
contentLen = fs.Read(buff, 0, bufferlength);
while (contentLen != 0)
{
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, bufferlength);
}
strm.Close();
fs.Close();
}
catch (Exception ex)
{
}
}
...........
...........
...........
...........
return View();
}
}
I found a solution for my problem and I want to share here, maybe a person can benefit
void UploadToFtp(HttpPostedFileBase uploadfile)
{
var uploadurl = "ftp://ftp.adress.com/";
var uploadfilename = uploadfile.FileName;
var username = "ftpusername";
var password = "ftppassword";
Stream streamObj = uploadfile.InputStream;
byte[] buffer = new byte[uploadfile.ContentLength];
streamObj.Read(buffer, 0, buffer.Length);
streamObj.Close();
streamObj = null;
string ftpurl = String.Format("{0}/{1}", uploadurl, uploadfilename);
var requestObj = FtpWebRequest.Create(ftpurl) as FtpWebRequest;
requestObj.Method = WebRequestMethods.Ftp.UploadFile;
requestObj.Credentials = new NetworkCredential(username, password);
Stream requestStream = requestObj.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Flush();
requestStream.Close();
requestObj = null;
}
Ensure the value in fileName is what you are expecting here:
string fileName = Path.Combine(uploadfile.FileName);
You most likely need to pass the path as a string, as well as the filename into the Combine method.
string fileName = Path.Combine(varFilePath, uploadfile.FileName);
Path.Combine expects an array of strings to combine: https://msdn.microsoft.com/en-us/library/system.io.path.combine%28v=vs.110%29.aspx
How to upload file by ftp using Asp.net MVC.
View
<form method="post" enctype="multipart/form-data">
<input type="file" id="postedFile" name="postedFile" />
<input type="submit" value="send" />
</form>
Controller ActionResult
[HttpPost]
public ActionResult Index(HttpPostedFileBase postedFile)
{
//FTP Server URL.
string ftp = "ftp://ftp.YourServer.com/";
//FTP Folder name. Leave blank if you want to upload to root folder.
string ftpFolder = "test/";
byte[] fileBytes = null;
string ftpUserName = "YourUserName";
string ftpPassword = "YourPassword";
//Read the FileName and convert it to Byte array.
string fileName = Path.GetFileName(postedFile.FileName);
using (BinaryReader br = new BinaryReader(postedFile.InputStream))
{
fileBytes = br.ReadBytes(postedFile.ContentLength);
}
try
{
//Create FTP Request.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftp + ftpFolder + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
//Enter FTP Server credentials.
request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
request.ContentLength = fileBytes.Length;
request.UsePassive = true;
request.UseBinary = true;
request.ServicePoint.ConnectionLimit = fileBytes.Length;
request.EnableSsl = false;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileBytes, 0, fileBytes.Length);
requestStream.Close();
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}
catch (WebException ex)
{
throw new Exception((ex.Response as FtpWebResponse).StatusDescription);
}
return View();
}
For upload large files you can add this line to your web.config
Thanks to Karthik Ganesan
<httpRuntime maxRequestLength="whatever value you need in kb max value is 2,147,483,647 kb" relaxedUrlToFileSystemMapping="true" />
under system.web section the default is 4 mb size limit
This is the method:
Getting the Length of the files give 0 already.
public void DownloadFtpContent(object sender ,string file, string filesdirectories,string fn)
{
try
{
BackgroundWorker bw = sender as BackgroundWorker;
string filenameonly = Path.GetFileName(file);
string ftpdirectories = Path.Combine(ftpcontentdir, filesdirectories);
string fileurl = "ftp://" + file;
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(fileurl);
reqFTP.Credentials = new NetworkCredential(UserName, Password);
reqFTP.UseBinary = true;
reqFTP.UsePassive = true;
reqFTP.KeepAlive = true;
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.Proxy = null;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
if (!Directory.Exists(ftpdirectories))
{
Directory.CreateDirectory(ftpdirectories);
}
FileStream writeStream = new FileStream(ftpdirectories + "\\" + filenameonly, FileMode.Create);
string fnn = ftpdirectories + "\\" + filenameonly;
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = responseStream.Read(buffer, 0, Length);
long FileSize = new FileInfo(fnn).Length;
string FileSizeDescription = GetFileSize(FileSize);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = responseStream.Read(buffer, 0, Length);
string SummaryText = String.Format("Transferred {0} / {1}", GetFileSize(bytesRead), FileSizeDescription);
bw.ReportProgress((int)(((decimal)bytesRead / (decimal)FileSize) * 100), SummaryText);
}
writeStream.Close();
response.Close();
}
catch (WebException wEx)
{
//MessageBox.Show(wEx.Message, "Download Error");
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message, "Download Error");
}
}
}
Already on this line the result is 0:
long FileSize = new FileInfo(fnn).Length;
In fnn i have: c:\myftpdownloads\root\Images\CB 967x330.jpg
Why the result of the Length is 0 ?
And the file is not 0kb size.
EDIT
This is how i'm calling the download method from backgroundworker dowork event:
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < numberOfFiles.Count; i++)
{
int fn = numberOfFiles[i].IndexOf(txtHost.Text, 0);
string fn1 = numberOfFiles[i].Substring(txtHost.Text.Length + 1, numberOfFiles[i].Length - (txtHost.Text.Length + 1));
string dirs = Path.GetDirectoryName(fn1);
string filename = Path.GetFileName(fn1);
ftpProgress1.DownloadFtpContent(sender,numberOfFiles[i], dirs, filename);
}
}
In fnn i have: c:\myftpdownloads\root\Images\CB 967x330.jpg Why the result of the Length is 0 ?
It doesn't really matter why the result of the length is 0. It does matter that you divide that number by 0 without any protection.
Just check before you divide:
if( FileSize != 0 ){...}
I am trying to Zip files from ftp server(using C#) and save zip file somewhere in my Local pc.I managed a code that could zip a file. But I am not sure how to loop through the ftp to zip all the files (max I should Zip 100 files and Zipfile should not exceed 100 megabytes.
That is the code I used to connect to ftp and Zip 1 file. How I can Zip several Files?
public void ProcessZipRequest(string strQueueID, string strBatchID, string strFtpPath)
{
int intReportCnt = 0;
string strZipFileName = "Order-" + strBatchID + "-" + strQueueID + "-" + DateTime.Now.ToString("MM-dd-yyyy-HH-mm") + ".zip";
strZipFileName = SafeFileName(strZipFileName);
//MemoryStream ms = new MemoryStream();
FileStream ms = new FileStream(#"c:\ZipFiles\nitest.zip", FileMode.Create);
ZipOutputStream oZipStream = new ZipOutputStream(ms); // create zip stream
oZipStream.SetLevel(9); // maximum compression
intReportCnt += 1;
string strRptFilename;
if (strQueueID != null)
{
MemoryStream outputStream = new MemoryStream();
// Get file path
string ftpFilePath = #"ftp://12.30.228.20/AOTest/Images/Report/11/595/45694/62_s.jpg";
// That is where I get 1 file from ftp (How loop here?)
strRptFilename = ftpFilePath.Substring(ftpFilePath.LastIndexOf("/") + 1);
FtpWebRequest reqFTP = (FtpWebRequest)System.Net.WebRequest.Create(ftpFilePath);
reqFTP.UseBinary = true;
reqFTP.KeepAlive = false;
reqFTP.Credentials = new NetworkCredential("username", "password");
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.Proxy = null;
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.Position = 0;
//Where I zip the files
ZipFile(ref outputStream, strRptFilename, ref oZipStream);
ftpStream.Close();
outputStream.Close();
if (response != null)
{
response.Close();
}
}
And that is ZipFile Method that zip the file:
public void ZipFile(ref MemoryStream msFile, string strFilename, ref ZipOutputStream oZipStream)
{
ZipEntry oZipEntry = new ZipEntry(strFilename);
oZipEntry.DateTime = DateTime.Now;
oZipEntry.Size = msFile.Length;
oZipStream.PutNextEntry(oZipEntry);
StreamUtils.Copy(msFile, oZipStream, new byte[4096]);
oZipStream.CloseEntry();
}
Have you considered using a foreach loop with a list.
Try something like
Filenamelist = new List <string>();
Then run a foreach loop to populate the list with your files. Something like
foreach (//listobject in //listname)
{
Filenamelist.Add(file.Name).
}
and from there run the same type of thing with a foreach loop to zip your
function.
Just a thought. Cheers!
I have a methode that copy folder structure from ftp to local folder and then copy all files that consists in them:
public void CreateDirectories()
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(Url);
request.Credentials = new NetworkCredential(Login, Pass);
request.Method = WebRequestMethods.Ftp.ListDirectory;
string soursePath = #"L:\Test";
StreamReader streamReader = new StreamReader(request.GetResponse().GetResponseStream());
string directoryName = streamReader.ReadLine();
while (directoryName != null)
{
//Create directories structure
if (directoryName.StartsWith("I") && !directoryName.Contains("p"))
{
string newPath = System.IO.Path.Combine(soursePath, directoryName);
if (!System.IO.Directory.Exists(newPath))
{
System.IO.Directory.CreateDirectory(newPath);
//get file list and invoke DownLoad(string directoryName, string fileName)
FtpWebRequest fileRequest = (FtpWebRequest)WebRequest.Create(Url + directoryName + "/");
fileRequest.Credentials = new NetworkCredential(Login, Pass);
fileRequest.Method = WebRequestMethods.Ftp.ListDirectory;
StreamReader fileStreamReader = new StreamReader(fileRequest.GetResponse().GetResponseStream());
string fileName = fileStreamReader.ReadLine();
while (fileName != null)
{
DownLoad(directoryName, fileName);
fileName = streamReader.ReadLine();
}
}
}
directoryName = streamReader.ReadLine();
}
request = null;
streamReader = null;
}
and the methode that copy current file:
public void DownLoad(string directoryName, string fileName)
{
string localPath = #"L:\Test\" + directoryName;
FtpWebRequest requestFileDownload = (FtpWebRequest)WebRequest.Create("ftp://ftp.equip.me/prod/" + directoryName + "/" + fileName);
requestFileDownload.Credentials = new NetworkCredential(Login, Pass);
requestFileDownload.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse responseFileDownload = (FtpWebResponse)requestFileDownload.GetResponse();
Stream responseStream = responseFileDownload.GetResponseStream();
FileStream writeStream = new FileStream(localPath + "\\" + fileName, 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);
}
responseStream.Close();
writeStream.Close();
requestFileDownload = null;
responseFileDownload = null;
}
But in line Stream responseStream = responseFileDownload.GetResponseStream(); it stop for nearly 40 seconds and then throw an exeption of timeout, and no one file has not been saved (file is small - 50 kb)
The first thing that you should try is to turn passive mode off since this is automatically blocked by most firewalls, but is the default mode of operation for ftpWebRequest.
Just below this line:
requestFileDownload.Method = WebRequestMethods.Ftp.DownloadFile;
and this one:
requestFileDownload.UsePassive = false;
Finding some problems copying a zip file from an FTP location. It is just copying and empty file so I think there is something wrong with my use of StreamReader or StreamWriter.
Here is the code:
//read through directory details response
string line = reader.ReadLine();
while (line != null)
{
if (line.EndsWith("zip")) //"d" = dir don't need "." or ".." dirs
{
FtpWebRequest downloadRequest = (FtpWebRequest)FtpWebRequest.Create("ftp://" + ftpHost + line); //new Uri("ftp://" + ftpServerIP + DestinationFolder + fileInf.Name));
downloadRequest.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["FilesUser"], ConfigurationManager.AppSettings["FilesPass"]);
downloadRequest.KeepAlive = false;
downloadRequest.UseBinary = true;
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
string folderToWrite = HttpContext.Current.Server.MapPath("~/Routing/RoutingFiles/");
string folderToSave = HttpContext.Current.Server.MapPath("~/Routing/");
StreamReader downloadRequestReader = new StreamReader(downloadRequest.GetResponse().GetResponseStream());
DirectoryInfo downloadDirectory = new DirectoryInfo(folderToWrite);
FileInfo file = new FileInfo(Path.Combine(downloadDirectory.FullName, line));
if (!file.Exists)
{
StreamWriter writer = new StreamWriter(Path.Combine(folderToWrite, line), false);
writer.Write(downloadRequestReader.ReadToEnd());
using (var downloadResponseStream = response.GetResponseStream())
{
}
}
}
}
By the time it gets to the bottom of that section, the file has been copied but is empty so I don't think I'm reading the stream correctly for a zip file. Anyone any ideas? I've seen talk of FileStream being better for downloading Zip files, but I couldn't get that to work either.
Thanks.
Here is an example that downloads a file from an ftp.
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpAddr + "test.zip");
request.Credentials = new NetworkCredential(userName, password);
request.UseBinary = true; // Use binary to ensure correct dlv!
request.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream writer = new FileStream("test.zip", FileMode.Create);
long length = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[2048];
readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
writer.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
}
responseStream.Close();
response.Close();
writer.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Edit I'm sorry for the error in previous code.
When correcting my previous code I found the following resource useful: example