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());
}
}
Related
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.
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();
I am new to C# and want to get list of file names in ftp directory. But i read some answer on other topics WebRequestMethods is for the single request.
Here is my current code getting FTP object for a specific files.
I want all files ends with ".txt" and want regex like "*.txt". How can I get all file names
in FTP directory?
reqFTP = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create(new Uri("ftp://95.0.181.84/bankToCompany/" + fileName));
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(obj.ftpUserName,obj.ftpPassword);
System.Net.FtpWebResponse response = (System.Net.FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
FileStream outputStream = new FileStream(obj.collectionFileDownloadAddress + renameAddress, FileMode.Create);
StreamReader reader = new StreamReader(responseStream);
string contents = reader.ReadToEnd();
How to: List Directory Contents with FTP
FTP is an old and horrible protocol to work with even in .Net but MSDN has some documentaion about it here.
Check out the "How to: Download Files with FTP" and "How to: Upload Files with FTP" links to the left aswell if you need.
private static void DownloadFile()
{
FtpWebRequest reqFTP;
WebResponse webResponse;
GetTheResponseFromFTP(out reqFTP, out webResponse, true);
FtpWebResponse response = (FtpWebResponse)webResponse;
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
using (StreamWriter streamWriter =
new StreamWriter("d:\\TestUnity.pdf", true))
{
streamWriter.WriteLine(reader.ReadToEnd());
}
reader.Close();
response.Close();
}
I have the above function, that download a file from the FTP location.
I am reading the text and trying to write it in a file in my local machine.
The PDf file generated is of the same size as it is downloaded but when I open the file its blank. Now I have two questions:
Can any one suggest how to save the downloaded file to a path which can be changed.
Whats the reason for the above problem mentioned.
From the documentation.
StreamWriter implements a TextWriter for writing characters to a stream
This means you haven't created a pdf file but a textfile with the *.pdf extension.
There are multiple utilities available to create a pdf
WkHtmlToPDF and ITextSharp are just two
Here is very simple code which works for me
void GeneratePDF(WebResponse response)
{
using (var streamFile = File.Create("E:/JSS.pdf"))
response.GetResponseStream().CopyTo(streamFile);
}