Testing FTP Output of a Stream - c#

Brand new to StackOverflow.... I'm writing a console app in C#. I'd like to verify that an Excel spreadsheet is streaming correctly using FTP.
The application calls a stored procedure, populates a datatable with the result set, reads the datatable into a stream and then FTP's that stream onto a 3rd party site. I'd like to upload the stream somewhere besides that actual 3rd party site just to verify everything shows properly on the other end. Looking for help with how to do that.
I've tried setting up a local FTP but received the following error when trying to create the FTPWebRequest:
"The requested URI is invalid for this FTP command."
FtpWebRequest myWebRequest = (FtpWebRequest)WebRequest.Create("ftp address");
I also tried Console.Out with no luck.
This is what my code to upload looks like:
StreamReader sourceStream;
using (sourceStream = new StreamReader(path))
{
fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
}
myWebRequest.ContentLength = fileContents.Length;
using (Stream requestStream = myWebRequest.GetRequestStream())
{
requestStream.Write(fileContents, 0, fileContents.Length);
}
using (FtpWebResponse response = (FtpWebResponse)myWebRequest.GetResponse())
{
Console.WriteLine($"Upload File Complete, status {response.StatusDescription}");
}

Related

c# how to list all files from ftp directory and read each file without downloading [duplicate]

I would like to load an excel file directly from an ftp site into a memory stream. Then I want to open the file in the FarPoint Spread control using the OpenExcel(Stream) method. My issue is I'm not sure if it's possible to download a file directly into memory. Anyone know if this is possible?
Yes, you can download a file from FTP to memory.
I think you can even pass the Stream from the FTP server to be processed by FarPoint.
WebRequest request = FtpWebRequest.Create("ftp://asd.com/file");
using (WebResponse response = request.GetResponse())
{
Stream responseStream = response.GetResponseStream();
OpenExcel(responseStream);
}
Using WebClient you can do nearly the same. Generally using WebClient is easier but gives you less configuration options and control (eg.: No timeout setting).
WebClient wc = new WebClient();
using (MemoryStream stream = new MemoryStream(wc.DownloadData("ftp://asd.com/file")))
{
OpenExcel(stream);
}
Take a look at WebClient.DownloadData. You should be able to download the file directory to memory and not write it to a file first.
This is untested, but something like:
var spreadSheetStream
= new MemoryStream(new WebClient().DownloadData(yourFilePath));
I'm not familiar with FarPoint though, to say whether or not the stream can be used directly with the OpenExcel method. Online examples show the method being used with a FileStream, but I'd assume any kind of Stream would be accepted.
Download file from URL to memory.
My answer does not exactly show, how to download a file for use in Excel, but shows how to create a generic-purpose in-memory byte array.
private static byte[] DownloadFile(string url)
{
byte[] result = null;
using (WebClient webClient = new WebClient())
{
result = webClient.DownloadData(url);
}
return result;
}

How to download an image from local server by url and save as byte array in uwp

I am working with an uwp application. In my app I want to download an image from a url which is nothing but local server. After downloading it I want to save the image in byte format in my app data.
I have used this code but getting exception as:
"Invalid port and invalid URI".
the code i used is:
HttpWebRequest imageRequest = (HttpWebRequest)WebRequest.Create(img.url);
WebResponse imageResponse = await imageRequest.GetResponseAsync();
Stream responseStream = imageResponse.GetResponseStream();
using (BinaryReader br = new BinaryReader(responseStream))
{
byte[] imageBytes = br.ReadBytes(500000);
br.Dispose();
}
responseStream.Dispose();
imageResponse.Dispose();
I Tried with httpclient also but getting the same exception.
How can I come out of this.
do not invent the wheel, uwp toolkit has got a nice ImageEx component that can do everything...download, cache, etc...

Open file from server using StreamReader

i´m trying to open a file that is allocated on server using streamreader and give me an error.
Code:
string path = #"localhost:91/Files/1/Documents/7d08d443-402f-47c7-978f-9f5069903019.csv";
StreamReader reader = new StreamReader(path);
ERROR: The given path's format is not supported
To get a stream representing a file downloaded from a web server you need something like this
WebRequest request = WebRequest.Create(#"http://servername:91/path/to/file.csv");
using (WebResponse response = request.GetResponse())
{
using (Stream stm = response.GetResponseStream())
{
//use response
}
}
Obviously replacing the url with your URL.
Old answer for opening a local file is below.
You should use a UNC path of the form
\\servername\sharename\path\to\file.csv
On a seperate point, when you create the StreamReader you should use a using block to ensure the streamreader gets closed promptly.

After transmission of text files blank lines appears in them

EDIT: Filezilla caused the problem, when i download files back from server it added new lines. I'm sorry for confusion.
This method upload files to ftp server and it's work fine, but in text files uploaded to server blank lines appear after every line("cr lf" appear), for example:
File:
First line
Second line
Third line
Uploaded file:
First line
Second line
Third line
Origin and uploaded files accordingly have different sizes, non-text files are the same.
Code:
private void sendFile(string In, string Out)
{
FtpWebRequest request = (FtpWebRequest) WebRequest.Create("ftp://domain//" + Out);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("username", "password");
FileStream sourceStream = new FileStream(In, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] fileContents = new byte[sourceStream.Length];
sourceStream.Read(fileContents, 0, (int) sourceStream.Length);
sorceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
}
How can i fix this?
EDIT: As the answer below doesn't seem to have helped (but I'm leaving it there for posterity as it shows better code) here are the next diagnostics steps I'd check:
How are you viewing the files? If at all possible, get onto the server directly rather than fetching the files again via a web browser or whatever.
What's the type of FTP server you're connecting to? Maybe there's a known issue.
Have you tried looking at what's actually being sent via Wireshark?
Have you tried sending the same files via a normal FTP client?
You should set FtpWebRequest.UseBinary to true in order to preserve the exact file contents. Otherwise the two systems will try to figure out line endings themselves, changing line terminators as they see fit. I very rarely think that's a good idea. (EDIT: UseBinary is actually true by default, but this sounds like the kind of problem introduced by using text mode... it certainly does no harm to make this explicit.)
Additionally:
You should be disposing of your FileStream via a using statement
You should be disposing of the request stream via a using statement
You should be taking note of the result of Stream.Read - it needn't always read the whole of the requested data in one go
You can either use File.ReadAllBytes to simply read the complete file data in one go, or use Stream.CopyTo (if you're using .NET 4) to copy the FileStream to the request stream (which won't set the content length, of course; I don't know whether this is a problem)
You're never calling GetResponse; it's unclear exactly what happens if you never fetch the response of an FtpWebRequest
Your parameter names don't match .NET naming conventions, and aren't very descriptive
So I would probably use:
private void SendFile(string inputFile, string outputPath)
{
FtpWebRequest request = (FtpWebRequest) WebRequest.Create
("ftp://domain//" + outputPath);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
request.Credentials = new NetworkCredential("username", "password");
byte[] fileContents = File.ReadAllBytes(inputFile);
request.ContentLength = fileContents.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileContents, 0, fileContents.Length);
}
// This *may* be necessary in order to validate that everything has happened
using (WebResponse response = request.GetResponse())
{
}
}
Its strange. I face the same problem and I was unable to fix it until I did not provide an extension in file. For Example if my file name was
abcfile
then I make it abcfile.dat and after that it shows me the uploaded file as actual file. I again upload file with abcfile.txt but this time again empty line problem appear in my uploaded file.
I suggest that you must provide extension to your file any except .txt.
The system that you're sending to uses different line endings to what your system uses. I can assume, because you get an extra line, that you're on Windows, and it uses CRLF endings. The system you're sending to recognises CR and LF as separate endings, so you get the extra lines.
For text, truncate the LF or the CR, see what happens. I have no clue about the differing file sizes.
In the top menu of FileZilla, set:
Transfer menu > Transfer type > binary
In the top menu of FileZilla, set:
Transfer menu > Transfer type > binary
It's working for me.

Upload FTP file to remote site from memory using C#

Am working on a project that requires uploading xml file to remote FTP site.
Is it possible to save xml string from memory to remote FTP site? ... from what i see i have to first write the file to local disk then read from disk and FTP to remote site.
I am using c#.
Thank you.
It's perfectly possible to use a MemoryStream instead of a FileStream to "write" data to an FTP server.
From the top of my head: (just a snippet of code, I asume you have the FTP stuff already)
var data = ASCIIEncoding.ASCII.GetBytes(yourXmlString);
using (var dataStream = new MemoryStream(data))
using (var requestStream = ftpRequest.GetRequestStream())
{
contentLength = dataStream.Read(buffer, 0, bufferLength);
while (contentLength != 0)
{
requestStream.Write(buffer,0,bufferLength);
contentLength = dataStream.Read(buffer, 0, bufferLength);
}
}
In other words, you simply need a stream, doesn't matter if it's a FileStream or MemoryStream

Categories

Resources