saving a binary file to ram in c# - c#

i am developing a flash tool for a mobile which sends a loader to it for further
communications.currently i receive the loader file through web request from a URL
and stores it in disk .below is the code i use
private void submitData()
{
try
{
ASCIIEncoding encoding = new ASCIIEncoding();
string cpuid = comboBox1.Text;
string postdata = "cpuid=" + cpuid;
byte[] data = encoding.GetBytes(postdata);
WebRequest request = WebRequest.Create("Http://127.0.0.1/fetch.php");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
Stream stream = request.GetRequestStream();
stream.Write(data, 0, data.Length);
stream.Close();
WebResponse response = request.GetResponse();
stream = response.GetResponseStream();
StreamReader sr = new StreamReader(stream);
string path = sr.ReadToEnd();
MessageBox.Show(path);
DateTime startTime = DateTime.UtcNow;
WebRequest request1 = WebRequest.Create("http://127.0.0.1/"+path);
WebResponse response2 = request1.GetResponse();
using (Stream responseStream = response2.GetResponseStream())
{
using (Stream fileStream = File.OpenWrite(#"e:\loader.mbn"))
{
byte[] buffer = new byte[4096];
int bytesRead = responseStream.Read(buffer, 0, 4096);
while (bytesRead > 0)
{
fileStream.Write(buffer, 0, bytesRead);
DateTime nowTime = DateTime.UtcNow;
if ((nowTime - startTime).TotalMinutes > 1)
{
throw new ApplicationException(
"Download timed out");
}
bytesRead = responseStream.Read(buffer, 0, 4096);
}
MessageBox.Show("COMPLETDED");
}
}
sr.Close();
stream.Close();
}
catch(Exception ex)
{
MessageBox.Show("ERR :" + ex.Message);
}
my question is there a way to store the file directly to the ram
and then use it from there
so far i tried to use Memory stream with no results.

There's nothing wrong with MemoryStream. You have to remember to reset the stream's position to the beginning if you want to use the data though.
//If the size is known, use it to avoid reallocations
use(var memStream=new MemoryStream(response.ContentLength))
use(var responseStream=response.GetResponseStream())
{
//Avoid blocking while waiting for the copy with CopyToAsync instead of CopyTo
await responseStream.CopyToAsync(memStream);
//Reset the position
memStream.Position = 0;
//Use the memory stream
...
}

Related

C# Why am I getting an out of memory exception when uploading large files?

I'm reading a large file into a stream, of which I'm filling a 4k buffer which I'm writing to a HttpWebRequest stream.
For some reason I'm getting out of memory exceptions, not sure why.
Am I doing something incorrectly?
My method:
public void StreamBlob(FileInfo file, Uri blobContainerSasUri, string containerName)
{
try
{
var method = "PUT";
var token = blobContainerSasUri.Query;
var requestUri =
new Uri($"https://{blobContainerSasUri.Host}/{containerName}/{string.Concat(file.Name, token)}");
using (var fileStream = file.OpenRead())
{
var request = (HttpWebRequest) WebRequest.Create(requestUri);
request.Method = method;
request.ContentType = MimeMapping.GetMimeMapping(file.FullName);
request.Headers.Add("x-ms-blob-type", "BlockBlob");
request.ContentLength = fileStream.Length;
request.AllowWriteStreamBuffering = false;
using (var serverStream = request.GetRequestStream())
{
var buffer = new byte[4096];
while (true)
{
var bytesRead = fileStream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
serverStream.Write(buffer, 0, bytesRead);
else
break;
}
}
using (var resp = (HttpWebResponse) request.GetResponse())
{
try
{
if (resp.StatusCode == HttpStatusCode.OK)
_logger.Log.Info("Received http response {resp}");
}
catch (Exception ex)
{
_logger.Log.Warn($"Received http response {resp}", ex)
}
}
}
}
catch (Exception ex)
{
_logger.Log.Warn($"Error uploading {file.Fullname}, ex")
}

HttpWebRequest Issue to remote server

I'm trying to upload files to a remote server (windows server 2008 R2) from my asp.net 1.1 (C#) Windows application (I know.. It's really old, sadly, that's what we have). When I try to upload, it's giving me an error: "The remote server returned an error: (404) Not Found.".
Here's the code I'm using:
Any ideas?
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uploadUrl);
req.Credentials = new NetworkCredential(uName,pwd);
req.Method = "PUT";
req.AllowWriteStreamBuffering = true;
// Retrieve request stream
Stream reqStream = req.GetRequestStream();
// Open the local file
FileStream rdr = new FileStream(txt_filename.Text, FileMode.Open);
// Allocate byte buffer to hold file contents
byte[] inData = new byte[4096];
// loop through the local file reading each data block
// and writing to the request stream buffer
int bytesRead = rdr.Read(inData, 0, inData.Length);
while (bytesRead > 0)
{
reqStream.Write(inData, 0, bytesRead);
bytesRead = rdr.Read(inData, 0, inData.Length);
}
rdr.Close();
reqStream.Close();
req.GetResponse();
The uploadUrl is like this: http://10.x.x.x./FolderName/Filename
Please use "POST" method instead of "PUT" and I guess it will work.
Edit:
Check the code below, it will help you.
public void UploadFile()
{
string fileUrl = #"enter file url here";
string parameters = #"image=" + Convert.ToBase64String(File.ReadAllBytes(fileUrl));
WebRequest req = WebRequest.Create(new Uri("location url here"));
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(parameters);
try
{
req.ContentLength = bytes.Length;
Stream s = req.GetRequestStream();
s.Write(bytes, 0, bytes.Length);
s.Close();
}
catch (WebException ex)
{
throw ex; //Request exception.
}
try
{
WebResponse res = req.GetResponse();
StreamReader sr = new StreamReader(req.GetResponseStream());
}
catch (WebException ex)
{
throw ex; //Response exception.
}
}
Enter fileUrl variable correctly and take care of uri while creating WebRequest instance, write the url of the locating folder.

Possible Infinite Loop when streaming response

We are trying to identify high CPU usage in services we have, and we believe there are a few potential areas that may be causing infinite loops. Below is code that we believe may potentially be causing an infinite loop. Is there anything specific that sticks out that may cause the while loop to run indefinitely?
WebRequest request = WebRequest.Create(Url);
request.ContentLength = formDataLength;
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
using (Stream rs = request.GetRequestStream())
{
ASCIIEncoding encoding = new ASCIIEncoding();
var postData = encoding.GetBytes(formData);
rs.Write(postData, 0, postData.Length);
string str = string.Empty;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream sm = response.GetResponseStream())
{
int totalBytesRead = 0;
long responseBytesToRead = 1024;
byte[] buffer = new byte[responseBytesToRead];
int bytesRead;
do
{
bytesRead = sm.Read(buffer, totalBytesRead, (int)(responseBytesToRead - totalBytesRead));
totalBytesRead += bytesRead;
} while (totalBytesRead < bytesRead);
request.Abort();
str = Encoding.Default.GetString(buffer);
}
}
return str;
}
From the MSDN documentation:
Return Value
Type: System.Int32 The total number of bytes read into
the buffer. This can be less than the number of bytes requested if
that many bytes are not currently available, or zero (0) if the end of
the stream has been reached.
0 indicates the end of the stream. The condition for reaching end of stream has already been defined. The condition you rely on could be unreliable and is unnecessary.
Try
while(bytesRead != 0)
It is better to use StreamReader
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
...
reader.ReadToEnd();
// or
while (!reader.EndOfStream)
{
// do read.
}

Out of Memory Exception - Reading large text file for HttpWebRequest

I am trying to read 500 MB text file to send it contents through HttpWebRequest. According to my requirement, I cannot send the data in chunks. Code is as follows :
using (StreamReader reader = new StreamReader(filename))
{
postData = reader.ReadToEnd();
}
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "text/plain";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
dataStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(dataStream))
{
responseFromServer = reader.ReadToEnd();
}
Console.WriteLine(responseFromServer);
dataStream.Close();
response.Close();
Reading such large file gives me out of memory exception. Is there a way I can do this?
Sounds like you may be encountering this documented issue with HttpWebRequest. Per the KB article, try setting the HttpWebRequest.AllowWriteStreamBuffering property to false.
All files are transferred in chunks - that's what an ethernet packet is; it's a single chunk of data. I would wager that the requirement really means "this file must be transferred in a single web service call."
Assuming that's the case, you'd read the data from disk into a 64KB buffer, and then write the buffer to the request.
request.ContentType = "text/plain";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
int BUFFER_SIZE = 65536;
byte[] buffer = new byte[BUFFER_SIZE];
using (StreamReader reader = new StreamReader(filename)) {
int count = 0;
while (true) {
int count = reader.Read(buffer, 0, BUFFER_SIZE);
dataStream.Write(buffer, 0, count);
if (count < BUFFER_SIZE) break;
}
}
dataStream.Close();

How to use WebRequest to POST some data and read response?

Need to have the server make a POST to an API, how do I add POST values to a WebRequest object and how do I send it and get the response (it will be a string) out?
I need to POST TWO values, and sometimes more, I see in these examples where it says string postData = "a string to post"; but how do I let the thing I am POSTing to know that there is multiple form values?
From MSDN
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create ("http://contoso.com/PostAccepter.aspx ");
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes (postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream ();
// Write the data to the request stream.
dataStream.Write (byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close ();
// Get the response.
WebResponse response = request.GetResponse ();
// Display the status.
Console.WriteLine (((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream ();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader (dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd ();
// Display the content.
Console.WriteLine (responseFromServer);
// Clean up the streams.
reader.Close ();
dataStream.Close ();
response.Close ();
Take into account that the information must be sent in the format key1=value1&key2=value2
Here's what works for me. I'm sure it can be improved, so feel free to make suggestions or edit to make it better.
const string WEBSERVICE_URL = "http://localhost/projectname/ServiceName.svc/ServiceMethod";
//This string is untested, but I think it's ok.
string jsonData = "{ \"key1\" : \"value1\", \"key2\":\"value2\" }";
try
{
var webRequest = System.Net.WebRequest.Create(WEBSERVICE_URL);
if (webRequest != null)
{
webRequest.Method = "POST";
webRequest.Timeout = 20000;
webRequest.ContentType = "application/json";
using (System.IO.Stream s = webRequest.GetRequestStream())
{
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(s))
sw.Write(jsonData);
}
using (System.IO.Stream s = webRequest.GetResponse().GetResponseStream())
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(s))
{
var jsonResponse = sr.ReadToEnd();
System.Diagnostics.Debug.WriteLine(String.Format("Response: {0}", jsonResponse));
}
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
Here's an example of posting to a web service using the HttpWebRequest and HttpWebResponse objects.
StringBuilder sb = new StringBuilder();
string query = "?q=" + latitude + "%2C" + longitude + "&format=xml&key=xxxxxxxxxxxxxxxxxxxxxxxx";
string weatherservice = "http://api.worldweatheronline.com/free/v1/marine.ashx" + query;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(weatherservice);
request.Referer = "http://www.yourdomain.com";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
Char[] readBuffer = new Char[256];
int count = reader.Read(readBuffer, 0, 256);
while (count > 0)
{
String output = new String(readBuffer, 0, count);
sb.Append(output);
count = reader.Read(readBuffer, 0, 256);
}
string xml = sb.ToString();
A more powerful and flexible example can be found here: C# File Upload with form fields, cookies and headers
Below is the code that read the data from the text file and sends it to the handler for processing and receive the response data from the handler and read it and store the data in the string builder class
//Get the data from text file that needs to be sent.
FileStream fileStream = new FileStream(#"G:\Papertest.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
byte[] buffer = new byte[fileStream.Length];
int count = fileStream.Read(buffer, 0, buffer.Length);
//This is a handler would recieve the data and process it and sends back response.
WebRequest myWebRequest = WebRequest.Create(#"http://localhost/Provider/ProcessorHandler.ashx");
myWebRequest.ContentLength = buffer.Length;
myWebRequest.ContentType = "application/octet-stream";
myWebRequest.Method = "POST";
// get the stream object that holds request stream.
Stream stream = myWebRequest.GetRequestStream();
stream.Write(buffer, 0, buffer.Length);
stream.Close();
//Sends a web request and wait for response.
try
{
WebResponse webResponse = myWebRequest.GetResponse();
//get Stream Data from the response
Stream respData = webResponse.GetResponseStream();
//read the response from stream.
StreamReader streamReader = new StreamReader(respData);
string name;
StringBuilder str = new StringBuilder();
while ((name = streamReader.ReadLine()) != null)
{
str.Append(name); // Add to stringbuider when response contains multple lines data
}
}
catch (Exception ex)
{
throw ex;
}

Categories

Resources