Is it possible to retreive file size on disk using webresponse?
if not, how can i retreive the file size?
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(finalUrl);
request.AllowAutoRedirect = true;
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.ServicePoint.ConnectionLimit = 24;
//request.Method = "HEAD";
var contentType = string.Empty;
using (WebResponse webResponse = request.GetResponse())
{
contentType = webResponse.ContentType;
using (Stream stream = webResponse.GetResponseStream())
{
using (MemoryStream memoryStream = new MemoryStream())
{
Byte[] buffer = new Byte[1024];
Int32 bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStream.Write(buffer, 0, bytesRead);
}
documentFile.Data = memoryStream.ToArray();
}
}
}
I think, it is the only way to get the file size information from the site before downloading the file is reading ContentLength header and there is no guarantee that server provide it.
var fileSize = webResponse.ContentLength;
or after download the file, you can get the length of the stream to retrieve size;
var fileSize = memoryStream.Length;
Related
I am using the following code to upload a image to my FTP server but I have a problem. If I use the code to check the dimension (height and width) of the image before upload then there is .png file created in the FTP server but it's empty (or invalid format) and if I remove the code to check the dimension, then the image is uploaded correctly. Does any have any idea on this?
public ActionResult UploadFile(int type, HttpPostedFileBase imagefile)
{
//check image height and width
using (System.Drawing.Image image = System.Drawing.Image.FromStream(imagefile.InputStream, true, true))
{
if (image.Width > 160 || image.Height > 160)
{
//do something here
}
}//end check image height and width
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftpPath" + "/" + imagefile.FileName);
request.Credentials = new NetworkCredential("ftpUserName", "ftpPassword");
request.Method = WebRequestMethods.Ftp.UploadFile;
var sourceStream = imagefile.InputStream;
Stream requestStream = request.GetRequestStream();
request.ContentLength = sourceStream.Length;
int BUFFER_SIZE = imagefile.ContentLength;
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = sourceStream.Read(buffer, 0, BUFFER_SIZE);
do
{
requestStream.Write(buffer, 0, bytesRead);
bytesRead = sourceStream.Read(buffer, 0, BUFFER_SIZE);
} while (bytesRead > 0);
sourceStream.Close();
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}
As mentioned, you are reading up all the stream when you load it into your Image. However, I don't think you can reset the position (i.e. "Seek") on a NetworkStream (your InputStream). Once you read it, it is gone.
One thing you can do though is to create a MemoryStream and use Stream.CopyTo to copy the contents into that. Then, you can do anything you like with it, including resetting the position to 0 to "read it a second time".
//example of resetting a stream named "s"
s.Position = 0;
Thanks guys for the reply they were very helpful but I fixed this issue by making slight changes on my code as below, I checked the image dimension after reading the input Stream. May be someone find this helpful.
public string ftpUpload(HttpPostedFileBase imagefile, string filename)
{
var sourceStream = imagefile.InputStream;
int BUFFER_SIZE = imagefile.ContentLength;
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = sourceStream.Read(buffer, 0, BUFFER_SIZE);
if (!CheckLogoDimension(sourceStream))
{
sourceStream.Close();
return "error";
}
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpRootPath + "/" + filename);
request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
request.Method = WebRequestMethods.Ftp.UploadFile;
Stream requestStream = request.GetRequestStream();
request.ContentLength = sourceStream.Length;
do
{
requestStream.Write(buffer, 0, bytesRead);
bytesRead = sourceStream.Read(buffer, 0, BUFFER_SIZE);
} while (bytesRead > 0);
sourceStream.Close();
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
return "Success";
}
I am trying to upload an image file via FTP in ASP.Net. The image file is uploaded to correct location but when I read or download it, it's corrupt. My code is given below
protected void FTPUpload()
{
//FTP Server URL.
string ftp = ConfigurationManager.AppSettings.Get("FTPServer");
//FTP Folder name.
string ftpFolder = "images/logos/";
//FTP Credentials
string ftpUsername = ConfigurationManager.AppSettings.Get("FTPUsername");
string ftpPassword = ConfigurationManager.AppSettings.Get("FTPPassword");
byte[] fileBytes = null;
//Read the FileName and convert it to Byte array.
string fileName = Path.GetFileName(fuLogo.FileName);
using (StreamReader fileStream = new StreamReader(fuLogo.PostedFile.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(ftpUsername, ftpPassword);
request.ContentLength = fileBytes.Length;
request.UsePassive = true;
request.UseBinary = true;
request.ServicePoint.ConnectionLimit = fileBytes.Length;
request.EnableSsl = false;
using (var requestStream = request.GetRequestStream())
{
CopyStream(fuLogo.PostedFile.InputStream, requestStream);
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
//lblMessage.Text += fileName + " uploaded.<br />";
response.Close();
}
catch (WebException ex)
{
throw new Exception((ex.Response as FtpWebResponse).StatusDescription);
}
}
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[1024000];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
}
Am I missing something? The file is uploaded perfectly but for some reason it gets corrupted.
This part smells:
using (StreamReader fileStream = new StreamReader(fuLogo.PostedFile.InputStream))
{
fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd());
fileStream.Close();
}
There should be no reason to first copy image to array (and use default text encoding/UTF8 decoding in the meantime) - just do stream-to-stream copy(see How do I copy the contents of one stream to another?):
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[32768];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write (buffer, 0, read);
}
}
So the ftp upload should be just
using (var requestStream = request.GetRequestStream())
{
CopyStream(fuLogo.PostedFile.InputStream, requestStream);
// no need to requestStream.Close(); - using does that for you
}
A web application that receive and send a pdf file with signature. I send pdf file in httpwebrequest to the application. But not receive that pdf file with httpwebresponse ?
My code
byte[] pdfFile = File.ReadAllBytes("c:\\sample.pdf");
WebRequest request = WebRequest.Create("URL");
request.Credentials = new NetworkCredential("Username", "Password");
request.Proxy.Credentials = new NetworkCredential("Username", "Password");
request.Method = "POST";
request.ContentLength = pdfFile.Length;
request.ContentType = "application/pdf";
Stream stream = request.GetRequestStream();
stream.Write(pdfFile, 0, pdfFile.Length);
stream.Close();
WebResponse resp = request.GetResponse();
var buffer = new byte[4096];
MemoryStream memoryStream = new MemoryStream();
Stream responseStream =resp.GetResponseStream();
{
int count;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write
(buffer, 0, responseStream.Read(buffer, 0, buffer.Length));
} while (count != 0);
}
resp.Close();
byte[] memoryBuffer = memoryStream.ToArray();
System.IO.File.WriteAllBytes(#"c:\sample1.txt", memoryBuffer);
int s = memoryBuffer.Length;
BinaryWriter binaryWriter =
new BinaryWriter(File.Open(#"c:\sample2.txt", FileMode.Create));
binaryWriter.Write(memoryBuffer);
binaryWriter.Close();
//Read Fully is :
public static byte[] ReadFully(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
One problem you have is in your reading:
int count;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, responseStream.Read(buffer, 0, buffer.Length));
} while (count != 0);
You're reading the buffer twice each time through the loop. The bytes you read the first time are lost because you overwrite them. Your code should be:
int count;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
} while (count != 0);
Also: I don't understand why you're writing the PDF to the request stream. Are you trying to send the PDF to a server and have it send the same file back?
What, exactly, are you trying to do here?
My problem is that when I view the uploaded file on my ftp server, there is no contents on it, it is empty. Why is this happening am I missing something in my code?
if (File.Exists("main.xml"))
{
using (Stream stream = new MemoryStream())
{
stream.Position = 0;
stream.Seek(0, SeekOrigin.Begin);
string uri = String.Format("ftp://{0}/{1}/{2}", "host", "wwwroot", "main.xml");
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
request.Credentials = new NetworkCredential("user", "pass");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.KeepAlive = false;
request.UseBinary = true;
request.UsePassive = true;
request.ContentLength = stream.Length;
request.EnableSsl = false;
int bufferLength = 2048;
byte[] buffer = new byte[bufferLength];
int contentLength;
Stream ftpStream = request.GetRequestStream();
contentLength = stream.Read(buffer, 0, bufferLength);
while (contentLength != 0)
{
ftpStream.Write(buffer, 0, contentLength);
contentLength = stream.Read(buffer, 0, bufferLength);
}
ftpStream.Flush();
ftpStream.Close();
}
}
else
{
MessageBox.Show("No file found.");
}
But when I try to insert this line of code above
MessageBox.Show(XDocument.Load("main.xml").ToString());
It has an output,
But when I try setting a breakpoint , when It reach while (contentLength != 0) it does not enter to it
EDIT
OK this is what it should have been
using (Stream stream = File.Open("main.xml", FileMode.Open))
If the file you're writing is always empty, it sounds like you aren't actually getting any of it. The first thing to check would be to see if that while (contentLength != 0) is ever entered in the first place.
Update: Also, as John pointed out, the request stream assignment is bad!
I need to download the file as http response for the current http request.
Until now I used code as
System.Uri uri = System.Web.HttpContext.Current.Request.Url;
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(
Path.Combine(uri.ToString(), filename));
httpRequest.Method = "GET";
using (HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse())
{
using (Stream responseStream = httpResponse.GetResponseStream())
{
using (FileStream localFileStream = new FileStream(
Path.Combine(localFolder, filename), FileMode.Open))
{
int bytesRead;
while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
totalBytesRead += bytesRead;
localFileStream.Write(buffer, 0, bytesRead);
}
}
}
}
But this code the request is only sending but not getting any responses...
Is this possible?
You should get the file off disk then use the Response.OutputStream to write the file directly to the response. Make sure to set the correct content headers so the browser will know what is coming.
FileInfo file = new FileInfo(Path.Combine(localFolder, filename));
int len = (int)file.Length, bytes;
Response.ContentType = "text/plain"; //Set the file type here
Response.AddHeader "Content-Disposition", "attachment;filename=" + filename;
context.Response.AppendHeader("content-length", len.ToString());
byte[] buffer = new byte[1024];
using(Stream stream = File.OpenRead(path)) {
while (len > 0 && (bytes =
stream.Read(buffer, 0, buffer.Length)) > 0)
{
Response.OutputStream.Write(buffer, 0, bytes);
len -= bytes;
}
}
Not sure, but it looks like your making a web request, getting the response stream, then attempting to buffer it out to localFolder. If so, FileMode.Open looks suspect ("should open an existing file..."?). Maybe use FileMode.Create.
MSDN ref
Also, does your web app needs to have write permissions to localFolder.