C# FTP File from Object - c#

I am trying to create an XML file from an object and save it to an FTP. My code successfully creates the file in the FTP, but the file just says NULL. PORequest is my object. Here is a screenshot:
Here is my code:
static void FTPXmlFile(PORequest req, string fileNameToCreate, string ftpUrl, string ftpPassword, string ftpUserName)
{
MemoryStream memoryStream = SerializeToStream(req);
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl + fileNameToCreate);
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
request.UseBinary = false;
byte[] buffer = new byte[memoryStream.Length];
memoryStream.Read(buffer, 0, buffer.Length);
memoryStream.Close();
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(buffer, 0, buffer.Length);
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}
static MemoryStream SerializeToStream(object o)
{
MemoryStream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, o);
return stream;
}
Update:
Here is the code that worked:
static MemoryStream GetMemoryStream(object req)
{
XmlSerializer xmlSerializer = new XmlSerializer(req.GetType());
string s = null;
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, req);
s = textWriter.ToString();
}
MemoryStream memoryStream = new MemoryStream();
StreamWriter writer = new StreamWriter(memoryStream);
writer.Write(s);
writer.Flush();
memoryStream.Position = 0;
return memoryStream;
}

Related

c# how to save IO.Stream to MemoryStream and save to PDF file on local folder

I am calling a third party service, which return a pdf file by IO.Stream. I need to change to MemoryStream, and save to a pdf file.
cRequestString = ".....";//You need to set up you own URL here.
//Make the API call
try
{
byte[] bHeaderBytes = System.Text.Encoding.UTF8.GetBytes(GetUserPasswordString()); //user and pa for third party call.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(cRequestString);
request.Method = WebRequestMethods.Http.Get;
request.PreAuthenticate = true;
request.ContentType = "application/pdf";
request.Accept = "application/pdf";
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(bHeaderBytes));
MemoryStream memStream;
WebResponse response = request.GetResponse();
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
memStream = new MemoryStream();
//read small blocks to show correctly
byte[] buffer = new Byte[1023];
int byteCount;
do
{
byteCount = stream.Read(buffer, 0, buffer.Length);
memStream.Write(buffer, 0, byteCount);
} while (byteCount > 0);
}
memStream.Seek(0, SeekOrigin.Begin);//set position to beginning
return memStream;
}
catch
{
return null;
}
//save MemoryStream to local pdf file
private void SavePDFFile(string cReportName, MemoryStream pdfStream)
{
//Check file exists, delete
if (File.Exists(cReportName))
{
File.Delete(cReportName);
}
using (FileStream file = new FileStream(cReportName, FileMode.Create, FileAccess.Write))
{
byte[] bytes = new byte[pdfStream.Length];
pdfStream.Read(bytes, 0, (int)pdfStream.Length);
file.Write(bytes, 0, bytes.Length);
pdfStream.Close();
}
}
You could do the following.
using (Stream stream = response.GetResponseStream())
using(MemoryStream memStream = new MemoryStream())
{
memStream = new MemoryStream();
stream.CopyTo(memoryStream);
// TODO : Rest of your task
}
More details on Stream.CopyTo on MSDN

Compressing data with GZipStream in C# and upload it to a webservice

I have an XML data which I would like to compress it using GZipStream and upload it to webservice. I would like to create the gzip file in memory instead of of creating it in local disk. I have tried the following:
public string class1(string url, string xml)
{
byte[] data = Encoding.ASCII.GetBytes(xml);
MemoryStream memory = new MemoryStream();
GZipStream gzip = new GZipStream(memory, CompressionMode.Compress, true);
gzip.Write(data, 0, data.Length);
byte[] zip=memory.ToArray();
HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create(url);
wReq.Method = "POST";
wReq.ContentType = "application/zip";
var reqStream = wReq.GetRequestStream();
reqStream.Write(zip,0,zip.Length);
reqStream.Close();
var wRes = wReq.GetResponse();
var resStream = wRes.GetResponseStream();
var resgzip = new GZipStream(resStream, CompressionMode.Decompress);
var reader = new StreamReader(resgzip);
var textResponse = reader.ReadToEnd();
reader.Close();
resStream.Close();
wRes.Close();
return textResponse;
}
After writing data to webservice the server unzips the file and processess it. While the server decompresses the data an exception is thrown in server "Premature end of file". Please help me in this.
Add below method to convert Stream to MemoryStream
public static MemoryStream Read(Stream stream)
{
MemoryStream memStream = new MemoryStream();
byte[] readBuffer = new byte[4096];
int bytesRead;
while ((bytesRead = stream.Read(readBuffer, 0, readBuffer.Length)) > 0)
memStream.Write(readBuffer, 0, bytesRead);
return memStream;
}
then call as below.
var wRes = wReq.GetResponse();
var memstream = Read(wRes.GetResponseStream());
var resgzip = new GZipStream(memstream, CompressionMode.Decompress);
var reader = new StreamReader(resgzip);
var textResponse = reader.ReadToEnd();

Binary stream '0' does not contain a valid BinaryHeader. invalid stream or object version change

I know like this question is existed but they not help to me, I want post a file of an action to ConvertToFLV action then that return an object converted to byte[], now when I want convert it to object I get The following error in ByteArrayToObject method, when reach to this line Video obj = (Video)binForm.Deserialize(memStream)
Binary stream '0' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization.
In addition please tell me contentType is correct in ConvertToFLV action?
public ActionResult Index()
{
WebRequest request = WebRequest.Create("http://localhost:25220/home/ConvertToFLV");
request.Method = "POST";
string path = Request.MapPath("~") + "2.wmv";
byte[] byteArray = System.IO.File.ReadAllBytes(path);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
byte[] convertedBytes = new byte[(int)response.ContentLength];
dataStream.Read(convertedBytes, 0, (int)response.ContentLength);
var obj = ByteArrayToObject(convertedBytes);
dataStream.Close();
response.Close();
return View();
}
public FileResult ConvertToFLV(HttpPostedFileBase file)
{
Stream stream = HttpContext.Request.InputStream;
byte[] result = new byte[HttpContext.Request.ContentLength];
stream.Read(result, 0, HttpContext.Request.ContentLength);
Video video = new Video { FLV = result };
return File(ObjectToByteArray(video), "application/x-www-form-urlencoded");
}
private Object ByteArrayToObject(byte[] arrBytes)
{
MemoryStream memStream = new MemoryStream();
memStream.Position = 0;
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
Video obj = (Video)binForm.Deserialize(memStream);
return obj;
}
private byte[] ObjectToByteArray(Video obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}

Encrypt File As Posted to FTP Site

I'm using VS 2010 (C#). I'm trying to encrypt (decrypt) a file as it is being uploaded (downloaded) from an FTP site. I thought this would be quicker than using a local temp file to encrypt before upload and decrypt after download. I get an error on the code below. I just can't seem to get the various stream types in alignment (i.e. FileStream, CryptoStream, and Stream). Any help is much appreciated.
public void Upload(byte[] desKey, byte[] desIV)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(Destination);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(UserName, Password);
FileStream fStream = File.Open(SourceFile, FileMode.OpenOrCreate);
CryptoStream responseStream = new CryptoStream(fStream, new DESCryptoServiceProvider().CreateDecryptor(desKey, desIV), CryptoStreamMode.Read);
byte[] fileContents = Encoding.UTF8.GetBytes(responseStream.ToString());
responseStream.Close(); ///ERROR here
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}
Unit Test:
public void CleanEncryptUploadTest()
{
FT.ftp uploadTest = new FT.ftp();
uploadTest.UserName = "ausername";
uploadTest.Password = "apassword";
uploadTest.SourceFile = "D:\\Temp\\Test\\file.txt";
uploadTest.Destination = "ftp://ftp.mysite.com/test2.txt";
byte[] key = ASCIIEncoding.ASCII.GetBytes("TestZone");
byte[] initVector = ASCIIEncoding.ASCII.GetBytes("TestZone");
uploadTest.Upload(key, initVector);
}
This worked for me, I used a memory stream and wrote the encrypted bytes to it instead. Also changed the cryptostream mode to write.
public void Upload(byte[] key, byte[] iv)
{
byte[] fileContents;
using (FileStream inputeFile = new FileStream(this.SourceFile, FileMode.Open, FileAccess.Read))
{
using (MemoryStream encryptedStream = new MemoryStream())
{
using (CryptoStream cryptostream = new CryptoStream(encryptedStream, new DESCryptoServiceProvider().CreateEncryptor(key, iv), CryptoStreamMode.Write))
{
byte[] bytearrayinput = new byte[inputeFile.Length];
inputeFile.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
fileContents = encryptedStream.ToArray();
}
}
}
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(this.Destination);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(this.UserName, this.Password);
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}

Downloading a torrent file with WebClient, results in corrupt file

I'm trying to download a .torrent file (not the contents of the torrent itself) in my .NET application.
Using the following code works for other files, but not .torrent. The resulting files is about 1-3kb smaller than if I download the file via a browser. When opening it in a torrent client, it says the torrent is corrupt.
WebClient web = new WebClient();
web.Headers.Add("Content-Type", "application/x-bittorrent");
web.DownloadFile("http://kat.ph/torrents/linux-mint-12-gnome-mate-dvd-64-bit-t6008958/", "test.torrent");
Opening the URL in a browser results in the file being downloaded correctly.
Any ideas as to why this would happen? Are there any good alternatives to WebClient that would download the file correctly?
EDIT: I've tried this as well as WebClient, and it results in the same thing:
private void DownloadFile(string url, string file)
{
byte[] result;
byte[] buffer = new byte[4096];
WebRequest wr = WebRequest.Create(url);
wr.ContentType = "application/x-bittorrent";
using (WebResponse response = wr.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
using (MemoryStream memoryStream = new MemoryStream())
{
int count = 0;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
} while (count != 0);
result = memoryStream.ToArray();
using (BinaryWriter writer = new BinaryWriter(new FileStream(file, FileMode.Create)))
{
writer.Write(result);
}
}
}
}
}
The problem that server returns content compressed by gzip and you download this compressed content to file. For such cases you should check the "Content-Encoding" header and use proper stream reader to decompress the source.
I modified your function to handle gzipped content:
private void DownloadFile(string url, string file)
{
byte[] result;
byte[] buffer = new byte[4096];
WebRequest wr = WebRequest.Create(url);
wr.ContentType = "application/x-bittorrent";
using (WebResponse response = wr.GetResponse())
{
bool gzip = response.Headers["Content-Encoding"] == "gzip";
var responseStream = gzip
? new GZipStream(response.GetResponseStream(), CompressionMode.Decompress)
: response.GetResponseStream();
using (MemoryStream memoryStream = new MemoryStream())
{
int count = 0;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
} while (count != 0);
result = memoryStream.ToArray();
using (BinaryWriter writer = new BinaryWriter(new FileStream(file, FileMode.Create)))
{
writer.Write(result);
}
}
}
}

Categories

Resources