C# Download/Read log file from FTP - c#

I have a few .log files on an FTP server. I need to download them on my drive. Alternatively, read and display contents. I've read related posts here, and came up with the code:
DOWNLOAD
public void DownloadFile(String infile)
{
String myUrl = String.Format("ftp://{0}/{1}", IpAddress, infile);
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(myUrl));
request.Credentials = new NetworkCredential(UserName, Password);
request.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
String output = String.Format("{0}", infile);
using (StreamWriter destination = new StreamWriter(output))
{
destination.Write(reader.ReadToEnd());
destination.Flush();
}
reader.Close();
response.Close();
}
READ
public string ReadTxtFile2(String infile)
{
WebClient request = new WebClient();
String url = String.Format("ftp://{0}/{1}", IpAddress, infile);
request.Credentials = new NetworkCredential(UserName, Password);
try
{
// also tried: String fileString = request.DownloadString(url);
byte[] newFileData = request.DownloadData(url);
string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
return fileString;
}
catch (WebException e)
{
return e.Message;
}
}
Somehow the download returns me an empty 0 kb file and a read() function outputs an empty contents. I can't find out why, any help?
NOTE: files do exist on server, I can list them.

Related

Upload a .txt file to a website page from a C# win forms app [duplicate]

I try upload a file to an FTP-server with C#. The file is uploaded but with zero bytes.
private void button2_Click(object sender, EventArgs e)
{
var dirPath = #"C:/Documents and Settings/sander.GD/Bureaublad/test/";
ftp ftpClient = new ftp("ftp://example.com/", "username", "password");
string[] files = Directory.GetFiles(dirPath,"*.*");
var uploadPath = "/httpdocs/album";
foreach (string file in files)
{
ftpClient.createDirectory("/test");
ftpClient.upload(uploadPath + "/" + Path.GetFileName(file), file);
}
if (string.IsNullOrEmpty(txtnaam.Text))
{
MessageBox.Show("Gelieve uw naam in te geven !");
}
}
The existing answers are valid, but why re-invent the wheel and bother with lower level WebRequest types while WebClient already implements FTP uploading neatly:
using (var client = new WebClient())
{
client.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
client.UploadFile("ftp://host/path.zip", WebRequestMethods.Ftp.UploadFile, localFile);
}
Easiest way
The most trivial way to upload a file to an FTP server using .NET framework is using WebClient.UploadFile method:
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
var url = "ftp://ftp.example.com/remote/path/file.zip";
client.UploadFile(url, #"C:\local\path\file.zip");
Advanced options
If you need a greater control, that WebClient does not offer (like TLS/SSL encryption, ascii/text transfer mode, active mode, transfer resuming, progress monitoring, etc), use FtpWebRequest. Easy way is to just copy a FileStream to an FTP stream using Stream.CopyTo:
var url = "ftp://ftp.example.com/remote/path/file.zip";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(#"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
Progress monitoring
If you need to monitor an upload progress, you have to copy the contents by chunks yourself:
var url = "ftp://ftp.example.com/remote/path/file.zip";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(#"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
byte[] buffer = new byte[10240];
int read;
while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
ftpStream.Write(buffer, 0, read);
Console.WriteLine("Uploaded {0} bytes", fileStream.Position);
}
}
For GUI progress (WinForms ProgressBar), see C# example at:
How can we show progress bar for upload with FtpWebRequest
Uploading folder
If you want to upload all files from a folder, see
Upload directory of files to FTP server using WebClient.
For a recursive upload, see
Recursive upload to FTP server in C#
.NET 5 Guide
async Task<FtpStatusCode> FtpFileUploadAsync(string ftpUrl, string userName, string password, string filePath)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(userName, password);
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (Stream requestStream = request.GetRequestStream())
{
await fileStream.CopyToAsync(requestStream);
}
using (FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync())
{
return response.StatusCode;
}
}
.NET Framework
public void UploadFtpFile(string folderName, string fileName)
{
FtpWebRequest request;
string folderName;
string fileName;
string absoluteFileName = Path.GetFileName(fileName);
request = WebRequest.Create(new Uri(string.Format(#"ftp://{0}/{1}/{2}", "127.0.0.1", folderName, absoluteFileName))) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = 1;
request.UsePassive = 1;
request.KeepAlive = 1;
request.Credentials = new NetworkCredential(user, pass);
request.ConnectionGroupName = "group";
using (FileStream fs = File.OpenRead(fileName))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
Stream requestStream = request.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Flush();
requestStream.Close();
}
}
How to use
UploadFtpFile("testFolder", "E:\\filesToUpload\\test.img");
use this in your foreach
and you only need to create folder one time
to create a folder
request = WebRequest.Create(new Uri(string.Format(#"ftp://{0}/{1}/", "127.0.0.1", "testFolder"))) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.MakeDirectory;
FtpWebResponse ftpResponse = (FtpWebResponse)request.GetResponse();
The following works for me:
public virtual void Send(string fileName, byte[] file)
{
ByteArrayToFile(fileName, file);
var request = (FtpWebRequest) WebRequest.Create(new Uri(ServerUrl + fileName));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UsePassive = false;
request.Credentials = new NetworkCredential(UserName, Password);
request.ContentLength = file.Length;
var requestStream = request.GetRequestStream();
requestStream.Write(file, 0, file.Length);
requestStream.Close();
var response = (FtpWebResponse) request.GetResponse();
if (response != null)
response.Close();
}
You can't read send the file parameter in your code as it is only the filename.
Use the following:
byte[] bytes = File.ReadAllBytes(dir + file);
To get the file so you can pass it to the Send method.
public static void UploadFileToFtp(string url, string filePath, string username, string password)
{
var fileName = Path.GetFileName(filePath);
var request = (FtpWebRequest)WebRequest.Create(url + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
using (var fileStream = File.OpenRead(filePath))
{
using (var requestStream = request.GetRequestStream())
{
fileStream.CopyTo(requestStream);
requestStream.Close();
}
}
var response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload done: {0}", response.StatusDescription);
response.Close();
}
In the first example must change those to:
requestStream.Flush();
requestStream.Close();
First flush and after that close.
This works for me,this method will SFTP a file to a location within your network.
It uses SSH.NET.2013.4.7 library.One can just download it for free.
//Secure FTP
public void SecureFTPUploadFile(string destinationHost,int port,string username,string password,string source,string destination)
{
ConnectionInfo ConnNfo = new ConnectionInfo(destinationHost, port, username, new PasswordAuthenticationMethod(username, password));
var temp = destination.Split('/');
string destinationFileName = temp[temp.Count() - 1];
string parentDirectory = destination.Remove(destination.Length - (destinationFileName.Length + 1), destinationFileName.Length + 1);
using (var sshclient = new SshClient(ConnNfo))
{
sshclient.Connect();
using (var cmd = sshclient.CreateCommand("mkdir -p " + parentDirectory + " && chmod +rw " + parentDirectory))
{
cmd.Execute();
}
sshclient.Disconnect();
}
using (var sftp = new SftpClient(ConnNfo))
{
sftp.Connect();
sftp.ChangeDirectory(parentDirectory);
using (var uplfileStream = System.IO.File.OpenRead(source))
{
sftp.UploadFile(uplfileStream, destinationFileName, true);
}
sftp.Disconnect();
}
}
publish date: 06/26/2018
https://learn.microsoft.com/en-us/dotnet/framework/network-programming/how-to-upload-files-with-ftp
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestGetExample
{
public static void Main ()
{
// Get the object used to communicate with the server.
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential("anonymous",
"janeDoe#contoso.com");
// Copy the contents of the file to the request stream.
byte[] fileContents;
using (StreamReader sourceStream = new StreamReader("testfile.txt"))
{
fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
}
request.ContentLength = fileContents.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileContents, 0, fileContents.Length);
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine($"Upload File Complete, status
{response.StatusDescription}");
}
}
}
}
Best way I've found is FluentFtp
You can find the repo here:
https://github.com/robinrodricks/FluentFTP
and the quickstart example here:
https://github.com/robinrodricks/FluentFTP/wiki/Quick-Start-Example.
And actually the WebRequest class recommended by a few people here, is not recommended by Microsoft anymore, check out this page:
https://learn.microsoft.com/en-us/dotnet/api/system.net.webrequest?view=net-5.0
// create an FTP client and specify the host, username and password
// (delete the credentials to use the "anonymous" account)
FtpClient client = new FtpClient("123.123.123.123", "david", "pass123");
// connect to the server and automatically detect working FTP settings
client.AutoConnect();
// upload a file and retry 3 times before giving up
client.RetryAttempts = 3;
client.UploadFile(#"C:\MyVideo.mp4", "/htdocs/big.txt",
FtpRemoteExists.Overwrite, false, FtpVerify.Retry);
// disconnect! good bye!
client.Disconnect();
I have observed that -
FtpwebRequest is missing.
As the target is FTP, so the NetworkCredential required.
I have prepared a method that works like this, you can replace the value of the variable ftpurl with the parameter TargetDestinationPath. I had tested this method on winforms application :
private void UploadProfileImage(string TargetFileName, string TargetDestinationPath, string FiletoUpload)
{
//Get the Image Destination path
string imageName = TargetFileName; //you can comment this
string imgPath = TargetDestinationPath;
string ftpurl = "ftp://downloads.abc.com/downloads.abc.com/MobileApps/SystemImages/ProfileImages/" + imgPath;
string ftpusername = krayknot_DAL.clsGlobal.FTPUsername;
string ftppassword = krayknot_DAL.clsGlobal.FTPPassword;
string fileurl = FiletoUpload;
FtpWebRequest ftpClient = (FtpWebRequest)FtpWebRequest.Create(ftpurl);
ftpClient.Credentials = new System.Net.NetworkCredential(ftpusername, ftppassword);
ftpClient.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
ftpClient.UseBinary = true;
ftpClient.KeepAlive = true;
System.IO.FileInfo fi = new System.IO.FileInfo(fileurl);
ftpClient.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 = ftpClient.GetRequestStream();
while (total_bytes > 0)
{
bytes = fs.Read(buffer, 0, buffer.Length);
rs.Write(buffer, 0, bytes);
total_bytes = total_bytes - bytes;
}
//fs.Flush();
fs.Close();
rs.Close();
FtpWebResponse uploadResponse = (FtpWebResponse)ftpClient.GetResponse();
string value = uploadResponse.StatusDescription;
uploadResponse.Close();
}
Let me know in case of any issue, or here is one more link that can help you:
https://msdn.microsoft.com/en-us/library/ms229715(v=vs.110).aspx

Upload a file with FTP in C# : The format of the URI could not be determined

I'm trying to upload a file with ftp in C#. for the moment, i try to do it locally:
static void Main(string[] args)
{
UploadFileToFtp("C:\\Utilisateurs\\arnaud\\Bureau\\yhyhyyh.rtf","root","root");
}
public static void UploadFileToFtp(string filePath, string username, string password)
{
var fileName = Path.GetFileName(filePath);
var request = (FtpWebRequest)WebRequest.Create("127.0.0.1/" + fileName);<---ERROR
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
using (var fileStream = File.OpenRead(filePath))
{
using (var requestStream = request.GetRequestStream())
{
fileStream.CopyTo(requestStream);
requestStream.Close();
}
}
var response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload done: {0}", response.StatusDescription);
response.Close();
}
I get the following error: (see above)
The format of the URI could not be determined
Thanks for your help
I think you are missing protocol: should be ftp://127.0.0.1/ instead of 127.0.0.1/. What's more, I suggest you to encode part of url that is stored in filePath. f.e:
var encoded = HttpUtility.UrlEncode(filePath);
var request = (FtpWebRequest)WebRequest.Create("ftp://127.0.0.1/" + encoded)
You need to reference System.Web assembly to use UrlEncode. More here.

Get upload time of file uploaded at ftp server

Can anyone please tell me from where would i get the time of uploaded file at the FTP server?
class listFiles
{
public static void Main(string[] args)
{
listFiles l = new listFiles();
l.getFileList(ftpConnection,"test123","pass123"); //ftp url
}
private void getFileList(string FTPAddress, string username, string password)
{
List<string> files = new List<string>();
try
{
//Create FTP request
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(FTPAddress);
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = true;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
{
//Application.DoEvents();
// string fileType = reader.ReadLine();
files.Add(reader.ReadLine());
}
//Clean-up
reader.Close();
responseStream.Close(); //redundant
response.Close();
}
catch (Exception)
{
Console.WriteLine("There was an error connecting to the FTP Server");
}
//If the list was successfully received, display it to the user
//through a dialog
if (files.Count != 0)
{
foreach (string file in files)
{
Console.WriteLine(file);
}
}
}
try with FtpWebResponse.LastModified Property
using (FtpWebResponse resp = (FtpWebResponse)request.GetResponse())
{
var lastModified = resp.LastModified ;
}
you need to get responses for each file, in your current code you have already a list of files, by using that file name build full path to ftp file you need to find the create date. after that create ftp request to that full ftp file path. then you can read the last modified date of response object.

Uploading files to FTP are corrupted once in destination

I'm creating a simple drag-file-and-upload-automatically-to-ftp windows application
and I'm using the MSDN code to upload the file to the FTP.
The code is pretty straight forward:
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(String.Format("{0}{1}", FTP_PATH, filenameToUpload));
request.Method = WebRequestMethods.Ftp.UploadFile;
// Options
request.UseBinary = true;
request.UsePassive = false;
// FTP Credentials
request.Credentials = new NetworkCredential(FTP_USR, FTP_PWD);
// Copy the contents of the file to the request stream.
StreamReader sourceStream = new StreamReader(fileToUpload.FullName);
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();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
writeOutput("Upload File Complete!");
writeOutput("Status: " + response.StatusDescription);
response.Close();
and it does get uploaded to the FTP
Problem is when I see the file on a browser, or simply download and try to see it on desktop I get:
I already used request.UseBinary = false; and request.UsePassive = false; but it does not seam to do any kind of good whatsoever.
What I have found out was that, the original file has 122Kb lenght and in the FTP (and after downloading), it has 219Kb...
What am I doing wrong?
By the way, the uploadFileToFTP() method is running inside a BackgroundWorker, but I don't really thing that makes any difference...
You shouldn't use a StreamReader but only a Stream to read binary files.
Streamreader is designed to read text files only.
Try with this :
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());
}
}
The problems are caused by your code decoding the binary data to character data and back to binary data. Don't do this.
Use the UploadFile Method of the WebClient Class:
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential(FTP_USR, FTP_PWD);
client.UploadFile(FTP_PATH + filenameToUpload, filenameToUpload);
}

How do I programatically download a file from a sharepoint site?

I have a sharepoint site that has an excel spreadsheet that I need to download on a schedulad basis
Is this possible?
Yes it is possible to download the file from sharepoint.
Once you have the url for the document, it can be downloaded using HttpWebRequest and HttpWebResponse.
attaching a sample code
DownLoadDocument(string strURL, string strFileName)
{
HttpWebRequest request;
HttpWebResponse response = null;
request = (HttpWebRequest)WebRequest.Create(strURL);
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
request.Timeout = 10000;
request.AllowWriteStreamBuffering = false;
response = (HttpWebResponse)request.GetResponse();
Stream s = response.GetResponseStream();
// Write to disk
if (!Directory.Exists(myDownLoads))
{
Directory.CreateDirectory(myDownLoads);
}
string aFilePath = myDownLoads + "\\" + strFileName;
FileStream fs = new FileStream(aFilePath, FileMode.Create);
byte[] read = new byte[256];
int count = s.Read(read, 0, read.Length);
while (count > 0)
{
fs.Write(read, 0, count);
count = s.Read(read, 0, read.Length);
}
// Close everything
fs.Close();
s.Close();
response.Close();
}
You can also use the GetItem API of Copy service to download a file.
string aFileUrl = mySiteUrl + strFileName;
Copy aCopyService = new Copy();
aCopyService.UseDefaultCredentials = true;
byte[] aFileContents = null;
FieldInformation[] aFieldInfo;
aCopyService.GetItem(aFileUrl, out aFieldInfo, out aFileContents);
The file can be retrieved as a byte array.
You can also do this:
try
{
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential("username", "password", "DOMAIN");
client.DownloadFile(http_path, path);
}
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
The link the to document in Sharepoint should be a static URL. Use that URL in whatever solution you have to grab the file on your schedule.
Why not just use wget.exe <url>. You can put that line in a batch file and run that through windows scheduler.

Categories

Resources