I am currently creating a CSV file and then I ftp that file.
This is working fine. However, I dont want to save the csv file, i want to create it to memory and then ftp it.
This is my current code:
private void Csv()
{
CsvExport eftExport = new CsvExport();
eftExport.AddRow();
eftExport["customer_reference"] = "Ref";
eftExport["landline"] = "01234567890";
string url = "C:/Content/Cms/DD/";
string fileName = "file.csv";
eftExport.ExportToFile(url + fileName);
this.FtpFile(url, fileName);
}
private void FtpFile(string url, string fileName)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://url.co.uk/" + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential ("Administrator", "pass");
StreamReader sourceStream = new StreamReader(url + fileName);
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();
}
but in stead of doing eftExport.ExportToFile(url + fileName); i dont want it to save to machine??
Use this to but it into a byte array:
byte[] buffer = eftExport.ExportToBytes();
Now:
requestStream.Write(buffer, 0, buffer.Length);
Use the ExportToBytes() function of your CsvExport class.
Then change your FtpFile() to accept a byte array and remove the stream reader
you should end up with quite a bit less code :)
If your CsvExport type has an ExportToStream or similar simply use that create the stream that you subsequently write to the requestStream.
Related
I am developing an ASP MVC website.
Now i need to upload files(.zip files) to my FTP server. For uploading i use this code.
This code uploads only those files which has size < 10 Mb.
for Example: when i upload a file with 150 MB size with this code it get damaged and the file size changed to 300 MB on my Ftp Server.
So can any one help me..
byte[] fileBytes = null;
//Read the FileName and convert it to Byte array.
string filename = Path.GetFileName(FileUpload1.FileName);
using (StreamReader fileStream = new StreamReader(FileUpload1.InputStream))
{
fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd());
fileStream.Close();
}
try
{
//Create FTP Request.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftp + ftpFolder + "/" + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
//Enter FTP Server credentials.
request.Credentials = new NetworkCredential(ftpUName, ftpPWord);
request.ContentLength = fileBytes.Length;
request.UsePassive = true;
request.UseBinary = true;
request.ServicePoint.ConnectionLimit = fileBytes.Length;
request.EnableSsl = false;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileBytes, 0, fileBytes.Length);
requestStream.Close();
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}
catch (WebException ex)
{
throw new Exception((ex.Response as FtpWebResponse).StatusDescription);
}
Add this to your web.config
<httpRuntime maxRequestLength="whatever value you need in kb max value is 2,147,483,647 kb" relaxedUrlToFileSystemMapping="true" />
under system.web section
the default is 4 mb size limit
Details here
It probably gets corrupt, because you are reading the data with utf8 encoded. You should read it in binary format.
Don't use:
using (StreamReader fileStream = new StreamReader(FileUpload1.InputStream))
{
fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd());
fileStream.Close();
}
You have to use File.ReadAllBytes or a BinaryReader(Stream)
https://msdn.microsoft.com/en-us/library/system.io.file.readallbytes(v=vs.110).aspx
https://msdn.microsoft.com/de-de/library/system.io.binaryreader(v=vs.110).aspx
for your example:
byte[] fileBytes = File.ReadAllBytes(Path.GetFileName(FileUpload1.FileName));
try
{
//Create FTP Request.
FtpWebRequest request = (FtpWebRequest)...
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();
i have code, where i send xml file to ftp server, but size of file on ftp server is smaller than original file. I'm trying to enable binary transmission, but result is still the same.
FileInfo f = new FileInfo("C:\\Users\\L\\Desktop\\data.xml");
long original_vel = f.Length;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://***");
request.UseBinary = true;
request.Method = WebRequestMethods.Ftp.GetFileSize;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("*****", "*****");
StreamReader sourceStream = new StreamReader(#"C:\\Users\\L\\Desktop\\data.xml");
byte[] fileContents = Encoding.Unicode.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
long ftp_vel = request.ContentLength;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
if (original_vel == ftp_vel)
{
response.Close();
}
else
{
Odesilani();
}
The size of original file is 294 672, but the file on ftp have 294 670.
The xml file on ftp is valid....But when i compare files in total comander, the original file have: FF FE 3C 00 3F 00.....and the file on ftp have 3C 00 3F 00...But the content of file is ok...:/
Have you any idea?
Is the XML file at the server valid? From your code, You are reading the file using Unicode. Files that are encoded using unicode usually have a character that is placed at the beginning of the file called the Byte Order Mark . That may be the reason you have a 2-Byte difference as it was lost during conversion.
UPDATE The Proper Byte Order Mark for any encoding is given by Encoding.GetPreamble()
The fix to the code above would be..
StreamReader sourceStream = new StreamReader(#"C:\\Users\\L\\Desktop\\data.xml");
//Get Preamble and File Contents
byte[] bom = Encoding.Unicode.GetPreamble();
byte[] content = Encoding.Unicode.GetBytes(sourceStream.ReadToEnd());
//Create Destination array
byte[] fileContents = new Byte[bom.Length + content.Length];
//Copy arrays into destination appending bom if available
Array.Copy(bom, 0, fileContents, 0, bom.Length);
Array.Copy(content, 0, fileContents, bom.Length, content.Length);
request.ContentLength = fileContents.Length;
long ftp_vel = request.ContentLength;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
if (original_vel == ftp_vel)
{
response.Close();
}
else
{
Odesilani();
}
aHi all:
I have created some .zip file on my web site, says 1110_1200_events.zip. I used the code to return .zip files in FileResult.
public FileResult GetEvents()
{
string fileName = "1020_1200_events.zip",
filePath = Server.MapPath("~/public/Event/" + fileName);
return File(filePath, "application/zip", fileName);
}
The problem is that if i used a WebRequest to read the stream of the file, I got the I/O exception at webResponse.GetResponseStream().Read(buffer, 0, buffer.Length): Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
Below is the code snippet. How do I work around it? Thank you.
var webRequest = WebRequest.Create(GetSPIUrl() + "SB/GetEvents");
webRequest.Method = "POST";
webRequest.ContentType = "application/zip";
StreamWriter writer = new StreamWriter(webRequest.GetRequestStream());
writer.WriteLine();
writer.Close();
// Send the data to the webserver
var webResponse = webRequest.GetResponse();
var reader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8);
FileInfo fi = new FileInfo("myData.zip");
using (FileStream fs = fi.OpenWrite())
{
byte[] buffer = new byte[8 * 1024];
int len;
while ((len = webResponse.GetResponseStream().Read(buffer, 0, buffer.Length)) > 0)
{
fs.Write(buffer, 0, len);
}
}
I have PGP files that I've verified as being valid, but at some point during the FTP upload, they become corrupt. When retrieved, I get an error message stating "Found no PGP information in these file(s)."
For what it's worth, the PGP is version 6.5.8, but I think that this is unimportant, as the files seem alright before they're uploaded.
My code is as follows for the file transfer, is there a setting or field that I've missed?
static void FTPUpload(string file)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.itginc.com" + "/" + Path.GetFileName(file));
request.UseBinary = true;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(ApplicationSettings["Username"], ApplicationSettings["Password"]);
StreamReader sr = new StreamReader(file);
byte[] fileContents = Encoding.UTF8.GetBytes(sr.ReadToEnd());
sr.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse resp = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload file complete, status {0}", resp.StatusDescription);
resp.Close();
string[] filePaths= Directory.GetFiles(tempPath);
foreach (string filePath in filePaths)
File.Delete(filePath);
}
Any help is appreciated
Hmmmm try not reading it into a byte array and instead doing something like this
using (var reader = File.Open(source, FileMode.Open))
{
var ftpStream = request.GetRequestStream();
reader.CopyTo(ftpStream);
ftpStream.Close();
}
PGP encodes data to binary stream, so your reading it via StreamReader and UTF8 probably breaks the data. FTP is unlikely to alter the data as you explicitly binary mode (though UseBinary is true by default so your setting should not do anything at all).