This question already has answers here:
Upload file and download file from FTP
(3 answers)
Closed 4 years ago.
i need to change the logic in an old system and im trying to get the downloading file to work, any ideas? i need to download the files using ftp in c# this is the code i found but i need to get that into a file instead of a stream
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://192.168.1.52/Odt/"+fileName+".dat");
request.Method = WebRequestMethods.Ftp.DownloadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
Console.WriteLine(reader.ReadToEnd());
Console.WriteLine("Download Complete, status {0}", response.StatusDescription);
reader.Close();
response.Close();
The suggestion from commenter Ron Beyer isn't bad, but because it involves decoding and re-encoding the text, there is a risk of data loss.
You can download the file verbatim by simply copying the request response stream to a file directly. That would look something like this:
// Some file name, initialized however you like
string fileName = ...;
using (Stream responseStream = response.GetResponseStream())
using (Stream fileStream = File.OpenWrite(filename))
{
responseStream.CopyTo(fileStream);
}
Console.WriteLine("Download Complete, status {0}", response.StatusDescription);
response.Close();
Related
This question already has an answer here:
Archive or image is corrupted after uploading to FTP and downloading back with FtpWebRequest
(1 answer)
Closed 4 years ago.
Here is my code.
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("path");
ftpRequest.Credentials = new NetworkCredential("log", "pass");
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
byte[] fileContent; //in this array you'll store the file's content
using (StreamReader sr = new StreamReader(#"pathToFile")) //'myFile.txt' is the file we want to upload
{
fileContent = Encoding.UTF8.GetBytes(sr.ReadToEnd()); //getting the file's content, already transformed into a byte array
}
using (Stream sw = ftpRequest.GetRequestStream())
{
sw.Write(fileContent, 0, fileContent.Length); //sending the content to the FTP Server
}
.txt files upload correctly with content but .pdf file not. Have no idea where problem is.
Why do you want to reinvent the upload file FTP while there is already WebClient implemented by Microsoft?
"STOR" means this is a upload in FTP
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential("log", "pass");
client.UploadFile("your_server", "STOR", filePath);
}
I'm trying to get into C# programming, but for some reason I'm stuck with trying to count all files that are uploaded on my ftp server. I already tried some code from stackoverflow
Code:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(server);
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential(user, password);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string names = reader.ReadToEnd();
reader.Close();
response.Close();
return names.Split(
new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).ToList();
He does connect to the server but just shows me there in only one file that he could find.
Here you can see the list as a string:
There is the file which he found:
All files that are uploaded on my server:
Here is my list (I don't understand why there are so many indexes):
Your code works for me, but #Ozug can be right that your server fails to use CRLF line endings.
A more robust (and more efficient too) implementation is:
List<string> names = new List<string>();
while (!reader.EndOfStream)
{
names.Add(reader.ReadLine());
}
It should handle even CR line endings.
See also C# class to parse WebRequestMethods.Ftp.ListDirectoryDetails FTP response.
I am trying to upload a file on FTP folder, but getting the following error.
The remote server returned an error: (550) File unavailable (e.g.,
file not found, no access)
I am using the following sample to test this:
// Get the object used to communicate with the server.
string path = HttpUtility.UrlEncode("ftp://host:port//01-03-2017/John, Doe S. M.D/file.wav");
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(path);
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential("user", "password");
// Copy the contents of the file to the request stream.
StreamReader sourceStream = new StreamReader(#"localpath\example.wav");
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();
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();
I am able to upload files on the parent folder 01-03-2017 but not in the target folder ROLLINS, SETH S. M.D which clearly has special characters in it.
I am able to upload files using FileZilla
I have tried to HttpUtility.UrlEncode but that did n't help
Thanks for your time and help.
You need to encode the spaces (and maybe commas) in the URL path, like:
string path =
"ftp://host:port/01-03-2017/" +
HttpUtility.UrlEncode("John, Doe S. M.D") + "/file.wav";
Effectively, you get:
ftp://host:port/01-03-2017/John%2c+Doe+S.+M.D/file.wav
Use something like this:
string path = HttpUtility.UrlEncode("ftp://96.31.95.118:2121//01-03-2017//ROLLINS, SETH S. M.D//30542_3117.wav");
or You can form a Uri using the following code and pass it webrequest.
var path = new Uri("ftp://96.31.95.118:2121//01-03-2017//ROLLINS, SETH S. M.D//30542_3117.wav");
The code works on a C# console application but did not work in Web Api Action. I could not manage to find the reason.
So I have used a free library for the same.
Posting the sample code from one of the examples available here:
So i have used FluentFtp libary available through Nuget.
using System;
using System.IO;
using System.Net;
using FluentFTP;
namespace Examples {
public class OpenWriteExample {
public static void OpenWrite() {
using (FtpClient conn = new FtpClient()) {
conn.Host = "localhost";
conn.Credentials = new NetworkCredential("ftptest", "ftptest");
using (Stream ostream = conn.OpenWrite("01-03-2017/John, Doe S. M.D/file.wav")) {
try {
// istream.Position is incremented accordingly to the writes you perform
}
finally {
ostream.Close();
}
}
}
}
}
}
Again, if the file is a binary file, StreamReader should not be used as explained here.
we currently have a *.BAT file that contains some FTP commands to download a file from our AS400 and save into a TEXT file. The BAT works fine and the text file will show the records inside the downloaded file one under the other.
Now, we wanted to get rid of this *.BAT file and use C# to download the file for us and save into a text file. The problem now is that the file we get contains all the records in ONE single line of string! they are no longer listed under each other.
here is the code we are using:
tpWebRequest request = default(FtpWebRequest);
FtpWebResponse response = default(FtpWebResponse);
StreamWriter writer = default(StreamWriter);
request = WebRequest.Create("*******URL******") as FtpWebRequest;
request.Credentials = new NetworkCredential("user", "pass");
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.UseBinary = true;
response = request.GetResponse() as FtpWebResponse;
writer = new StreamWriter(Server.MapPath("/filename.txt"));
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(37))) //37 for IBM encoding
{
writer.WriteLine(reader.ReadToEnd());
}
writer.Close();
response.Close();
Any idea why we are getting this? and why the simple DOS FTP command work better than our code?
Thanks a lot! :)
ASCII mode will add record delimiters when downloading a physical file. It is the default transfer mode of most ftp clients.
request.UseBinary = false;
Specifying false causes the FtpWebRequest to send a "Type A" command to the server.
Data Transfer Methods
Transferring QSYS.LIB files
The problem might be simple: you read the whole document at once. You need to read every line seperately:
using(StreamReader sr = new StreamReader(fs))
{
while(!sr.EndOfStream)
{
Console.WriteLine(sr.ReadLine());
}
}
In my application I use the WebClient class to download files from a Webserver by simply calling the DownloadFile method. Now I need to check whether a certain file exists prior to downloading it (or in case I just want to make sure that it exists). I've got two questions with that:
What is the best way to check whether a file exists on a server without transfering to much data across the wire? (It's quite a huge number of files I need to check)
Is there a way to get the size of a given remote file without downloading it?
Thanks in advance!
WebClient is fairly limited; if you switch to using WebRequest, then you gain the ability to send an HTTP HEAD request. When you issue the request, you should either get an error (if the file is missing), or a WebResponse with a valid ContentLength property.
Edit: Example code:
WebRequest request = WebRequest.Create(new Uri("http://www.example.com/"));
request.Method = "HEAD";
using(WebResponse response = request.GetResponse()) {
Console.WriteLine("{0} {1}", response.ContentLength, response.ContentType);
}
When you request file using the WebClient Class, the 404 Error (File Not Found) will lead to an exception. Best way is to handle that exception and use a flag which can be set to see if the file exists or not.
The example code goes as follows:
System.Net.HttpWebRequest request = null;
System.Net.HttpWebResponse response = null;
request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create("www.example.com/somepath");
request.Timeout = 30000;
try
{
response = (System.Net.HttpWebResponse)request.GetResponse();
flag = 1;
}
catch
{
flag = -1;
}
if (flag==1)
{
Console.WriteLine("File Found!!!");
}
else
{
Console.WriteLine("File Not Found!!!");
}
You can put your code in respective if blocks.
Hope it helps!
What is the best way to check whether a file exists on a server
without transfering to much data across the wire?
You can test with WebClient.OpenRead to open the file stream without reading all the file bytes:
using (var client = new WebClient())
{
Stream stream = client.OpenRead(url);
// ^ throws System.Net.WebException: 'Could not find file...' if file is not present
stream.Close();
}
This will indicate if the file exists at the remote location or not.
To fully read the file stream, you would do:
using (var client = new WebClient())
{
Stream stream = client.OpenRead(url);
StreamReader sr = new StreamReader(stream);
Console.WriteLine(sr.ReadToEnd());
stream.Close();
}
In case anyone stuck with ssl certificate issue
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback
(
delegate { return true; }
);
WebRequest request = WebRequest.Create(new Uri("http://.com/flower.zip"));
request.Method = "HEAD";
using (WebResponse response = request.GetResponse())
{
Console.WriteLine("{0} {1}", response.ContentLength, response.ContentType);
}