How can I save files from ftp? - c#

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;

Related

File uploaded to ftp server is corrupted c#

I'm not sure why my file is corrupted. I'm not using StreamReader which has been a common problem that most have had. It uploads successfully I just can't seem to find the issue on why the file is corrupted even after searching through the various solved stack overflow questions.
public ActionResult UploadFtpFile(HttpPostedFileBase promoImgFile)
{
bool isSavedSuccessfully = true;
string fileName = null;
string completeDPath = "xxxxx";
string username = "xxxx";
string password = "xxxxx";
FtpWebRequest ftpClient;
FtpWebRequest ftpRequest;
List<string> directories = new List<string>();
try
{
foreach (string fileItemName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileItemName];
fileName = file.FileName;
if (file != null && file.ContentLength > 0)
{
//Create FtpWebRequest object
ftpClient = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + completeDPath + "/" + fileName));
//Set request method
ftpClient.Method = WebRequestMethods.Ftp.UploadFile;
//Set Credentials
ftpClient.Credentials = new NetworkCredential(username, password);
//Opens a file to read
Stream objFile = file.InputStream;
//By default KeepAlive is true, where the control connection is not closed after a command is executed.
ftpClient.KeepAlive = true;
//Set the data transfer type
ftpClient.UseBinary = true;
//Set content length
ftpClient.ContentLength = file.ContentLength;
//Get Stream of the file
Stream objStream = ftpClient.GetRequestStream();
byte[] buffer = new byte[objFile.Length];
//Write file content
objStream.Write(buffer, 0, buffer.Length);
objStream.Close();
objFile.Close();
}
}
}
catch(Exception ex)
{
throw ex;
isSavedSuccessfully = false;
}
//return Json(new { promoImgFile = directories });
return RedirectToAction("Index", "Home", new { promoImgFile = directories });
}
It's this line right here:
Stream objFile = file.InputStream;
Years of learning, I figured out one thing that works:
MemoryStream ms = new MemoryStream();
file.InputStream.CopyTo(ms);
Then work off the MemoryStream.
Example (for text)
Docs: MSDN
The important part for your issue:
StreamReader sourceStream = new StreamReader("testfile.txt");
byte [] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
Example (for an image)
byte [] imageData = File.ReadAllBytes(imageSource);
request.ContentLength = imageData.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(imageData, 0, imageData.Length);
requestStream.Close();

SFTP File Upload [duplicate]

This question already has answers here:
SFTP Libraries for .NET [closed]
(8 answers)
Closed 6 years ago.
I have created file Upload using FTP (code given below) and it is working Correctly. But now I have to do a file Upload Using SFTP
Kindly request you to guide me on the library to be used for sftp in VS.
class Program
{
static void Main(string[] args)
{
try
{
string path = ConfigurationManager.AppSettings["filepath"];
string[] files = Directory.GetFiles(path, #"*.xlsx");
string FtpServer = ConfigurationManager.AppSettings["ftpurl"];
string Username = ConfigurationManager.AppSettings["username"];
string Password = ConfigurationManager.AppSettings["password"];
string directory = ConfigurationManager.AppSettings["directoryname"];
if (files != null)
{
foreach (string file in files)
{
int port = 22;
FileInfo fi = new FileInfo(file);
string fileName = fi.Name;
string fileurl = path + #"/" + fileName;
string ftpFile = FtpServer + #":" + port + #"/" + directory + #"/" + fileName;
FtpWebRequest myRequest = (FtpWebRequest)FtpWebRequest.Create(ftpFile);
//WebRequest myreq = (WebRequest)WebRequest.Create(ftpFile);
//myreq.Credentials = new NetworkCredential(Username, Password);
myRequest.Credentials = new NetworkCredential(Username, Password);
//WebProxy wb = new WebProxy("http://proxy4.wipro.com:8080");
//wb.Credentials = new NetworkCredential(Username, Password);
//myRequest.Proxy = wb;
myRequest.Method = WebRequestMethods.Ftp.UploadFile;
myRequest.Timeout = 1000000;
myRequest.UseBinary = true;
myRequest.KeepAlive = true;
myRequest.ContentLength = fi.Length;
byte[] buffer = new byte[4097];
int bytes = 0;
int total_bytes = (int)fi.Length;
System.IO.FileStream fs = fi.OpenRead();
System.IO.Stream rs = myRequest.GetRequestStream();
while (total_bytes > 0)
{
bytes = fs.Read(buffer, 0, buffer.Length);
rs.Write(buffer, 0, bytes);
total_bytes = total_bytes - bytes;
}
fs.Close();
rs.Close();
//WebRequest upload = (WebRequest)myreq.GetResponse();
FtpWebResponse uploadResponse = (FtpWebResponse)myRequest.GetResponse();
Console.WriteLine("Upload File Successful");
uploadResponse.Close();
}
}
}
catch (Exception ex)
{
FTPDirectory.logfile.LogInfo("Error in Uploading file in ftp://ftp.xactlycorp.com" + ex.Message);
}
}
}
You can also use http://www.chilkatsoft.com/ssh-sftp-dotnet.asp
Ive used this a lot of stuff and its really good.
There is something named SharpSSH that you can use:
http://www.tamirgal.com/blog/page/SharpSSH.aspx
Example usage:
sftp = new Tamir.SharpSsh.Sftp(ipAddress, username, password);
sftp.Connect();
sftp.Get(sourcePath, destinationPath);
sftp.Close();

How I can loop through FTP to zip all the files?

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!

FTP uploading error

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.

Downloading ZIP file from FTP and copying to folder within website

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

Categories

Resources