I want to calculate downloading time in my ftp download manager.
I am using these code to download file through ftp.
try
{
string DirectoryCreate = localPath;
if (!Directory.Exists(DirectoryCreate))
{
Directory.CreateDirectory(DirectoryCreate);
}
FtpWebRequest requestFileDownload = (FtpWebRequest)WebRequest.Create("ftp://xxxxxx.com);
requestFileDownload.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse responseFileDownload = (FtpWebResponse)requestFileDownload.GetResponse();
Stream responseStream = responseFileDownload.GetResponseStream();
FileStream writeStream = new FileStream(localPath + "\\" + fileName, FileMode.Create);
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = responseStream.Read(buffer, 0, Length);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = responseStream.Read(buffer, 0, Length);
}
responseStream.Close();
writeStream.Close();
requestFileDownload = null;
responseFileDownload = null;
}
catch(WebException ex)
{
}
Can anyone please say me what i should change in my code for calculating download time.
There would be great appreciation if someone could help me.
DateTime t1 = DateTime.Now;
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = responseStream.Read(buffer, 0, Length);
}
DateTime t2 = DateTime.Now;
TimeSpan diff = t2 - t1;//you can return diff or display it using its properties ..
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int bytesRead = responseStream.Read(buffer, 0, Length);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = responseStream.Read(buffer, 0, Length);
}
responseStream.Close();
writeStream.Close();
requestFileDownload = null;
responseFileDownload = null;
}
catch(WebException ex)
{
}
stopwatch.Stop();
stopwatch.Elapsed // this will give you the elapsed time
Related
This question already has answers here:
FtpWebRequest FTP download with ProgressBar
(3 answers)
Closed 2 years ago.
I'm with something new, I'm blocked and I don't know how to do the truth.
I am making a program that downloads by FTP to do a series of steps, the first thing is to download.
Here I have the code that makes the download which works perfect:
public static void DescargarFichero(string ficFTP, string user, string pass, string dirLocal, Boolean UsePassive, Boolean UseBinary)
{
FtpWebRequest dirFtp = ((FtpWebRequest)FtpWebRequest.Create(ficFTP));
dirFtp.KeepAlive = true;
dirFtp.UsePassive = UsePassive;
dirFtp.UseBinary = UseBinary;
// Los datos del usuario (credenciales)
NetworkCredential cr = new NetworkCredential(user, pass);
dirFtp.Credentials = cr;
FtpWebResponse response = (FtpWebResponse)dirFtp.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
using (FileStream writer = new FileStream(dirLocal, FileMode.Create))
{
long length = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[2048];
readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
writer.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
Console.WriteLine("Descargando...");
}
}
reader.Close();
response.Close();
}
I am doing tests in a console application, but the future is to use windows form and that it looks good, my blocking is this: How can I show this to happen:
while (readCount > 0)
{
writer.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
Console.WriteLine("Descargando...");
}
I can find out that this function is executing and that it is "downloading" I am looking for that every time that cycle is iterating I can return a value without having to break the cycle. My idea is to be able to say If Value is = X then "downloading"
Newbie question? Yes, I am blocked and I don't know how to get out of the "rat race". I hope you can help me.
Showing progress percentage
readCount = responseStream.Read(buffer, 0, bufferSize);
int current = 0; //Create a new int variable to count iterations
while (readCount > 0)
{
writer.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
current++; //Increment the counter
double percentProgress = (current/readCount) * 100; //Calculate the percent
string percentString = percentProgress.ToString() + "%"; //Append a %
Console.WriteLine(percentString); //Write to console
}
See this post if you wish to keep it on one line: Can Console.Clear be used to only clear a line instead of whole console?
My requirement is to transfer a zip file of size 400MB or more; The following code works for at least 40MB; But for more I would have to change byte[] bytes = new byte[50000000]; to byte[] bytes = new byte[400000000]; and maxRequestLength to maxRequestLength="409600";
The problem is byte[] bytes = new byte[100000000]; returns an error regarding insufficient space. So how can I transfer large files using WebClient??
WebClient client = new WebClient();
client.AllowWriteStreamBuffering = true;
UriBuilder ub = new UriBuilder("http://localhost:57596/UploadImages.ashx");
ub.Query = "ImageName=" + "DataSet" + DataSetId + ".zip";
client.OpenWriteCompleted += (InputStream, eArguments) =>
{
try
{
using (Stream output = eArguments.Result)
{
output.Write(ImagesAux, 0, (int)ImagesAux.Length);
//numeroimagem++;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
//throw;
}
};
client.OpenWriteAsync(ub.Uri);
in UploadImages.ashx
public void ProcessRequest(HttpContext context)
{
//context.Response.ContentType = "text/plain";
//context.Response.Write("Hello World");
string ImageName = context.Request.QueryString["ImageName"];
string UploadPath = context.Server.MapPath("~/ServerImages/");
using (FileStream stream = File.Create(UploadPath + ImageName))
{
byte[] bytes = new byte[50000000]; //
int bytesToRead = 0;
while ((bytesToRead =
context.Request.InputStream.Read(bytes, 0, bytes.Length)) != 0)
{
stream.Write(bytes, 0, bytesToRead);
stream.Close();
}
}
}
in Web.config
<httpRuntime targetFramework="4.5" maxRequestLength="40960"/>
You should never load everything in memory then write all back to disk, but instead you should load pieces and write them to disk while you are reading them.
When you've done reading you close the stream you are writing to.
Otherwise as soon as you reach sizes as GB you can get an OutOfMemory really quick.
So I would change the writing bytes to disk from this:
using (FileStream stream = File.Create(UploadPath + ImageName))
{
byte[] bytes = new byte[50000000]; //
int bytesToRead = 0;
while ((bytesToRead = context.Request.InputStream.Read(bytes, 0, bytes.Length)) != 0)
{
stream.Write(bytes, 0, bytesToRead);
stream.Close();
}
}
to this:
using (FileStream stream = File.Create(UploadPath + ImageName))
{
byte[] bytes = new byte[1024];
long totalBytes = context.Request.InputStream.Length;
long bytesRead = 0;
int bytesToRead = bytes.Length;
if (totalBytes - bytesRead < bytes.Length)
bytesToRead = (int)(totalBytes - bytesRead);
bytes = new byte[bytesToRead];
while ((bytesToRead = context.Request.InputStream.Read(bytes, bytesRead, bytes.Length)) != 0)
{
stream.Write(bytes, bytesRead, bytes.Length);
bytesRead += bytes.Length;
if (totalBytes - bytesRead < bytes.Length)
bytesToRead = (int)(totalBytes - bytesRead);
bytes = new byte[bytesToRead];
}
stream.Close();
}
1024 would be the buffer size.
I want to write my http response to a file but my file is always empty. Why?
using (Stream outputfile = File.OpenWrite(objecttype + ".txt"))
{
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = context.Response.OutputStream.Read(buffer, 0, buffer.Length)) > 0)
{
outputfile.Write(buffer, 0, bytesRead);
}
outputfile.Flush();
outputfile.Close();
}
I need to control cache on the file-level.
Sometimes I can get a 304 response when the file is reloaded - but mostly not.
What am I doing wrong here with my caching settings?
public static void GetAndOutputFile(string url, int maxAgeInHours, string key)
{
Stream stream = null;
const int bytesToRead = 100000;
byte[] buffer = new Byte[bytesToRead];
try
{
HttpWebRequest fileReq = (HttpWebRequest) HttpWebRequest.Create(url);
HttpWebResponse fileResp = (HttpWebResponse) fileReq.GetResponse();
if (fileReq.ContentLength > 0)
fileResp.ContentLength = fileReq.ContentLength;
stream = fileResp.GetResponseStream();
var resp = HttpContext.Current.Response;
resp.ContentType = fileResp.ContentType;
//Set cache
resp.Cache.SetCacheability(HttpCacheability.Public);
resp.Cache.SetSlidingExpiration(false);
resp.Cache.SetLastModified(DateTime.Parse("1/1/2001 00:00:01AM"));
resp.Cache.SetMaxAge(TimeSpan.FromHours(maxAgeInHours));
resp.Cache.SetExpires(DateTime.UtcNow.AddHours(maxAgeInHours));
MemoryStream ms = new MemoryStream();
int length;
do
{
if (resp.IsClientConnected)
{
length = stream.Read(buffer, 0, bytesToRead);
resp.OutputStream.Write(buffer, 0, length);
ms.Write(buffer, 0, length);
resp.Flush();
buffer = new Byte[bytesToRead];
}
else
{
length = -1;
}
} while (length > 0); //Repeat until no data is read
}
finally
{
if (stream != null)
{
//Close the input stream
stream.Close();
stream.Dispose();
}
}
}
}
Found the solution. Key issue is that must set the 304 yourself in .NET.
public static void GetAndOutputFile(string url, int maxAgeInHours, string key)
{
if (!String.IsNullOrEmpty(HttpContext.Current.Request.Headers["If-Modified-Since"]))
{
CultureInfo provider = CultureInfo.InvariantCulture;
var lastMod = DateTime.ParseExact(HttpContext.Current.Request.Headers["If-Modified-Since"], "r", provider).ToLocalTime();
if (lastMod < DateTime.UtcNow.ToLocalTime())
{
HttpContext.Current.Response.StatusCode = 304;
HttpContext.Current.Response.StatusDescription = "Not Modified";
return;
}
}
Stream stream = null;
const int bytesToRead = 100000;
byte[] buffer = new Byte[bytesToRead];
try
{
HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse fileResp = (HttpWebResponse)fileReq.GetResponse();
if (fileReq.ContentLength > 0)
fileResp.ContentLength = fileReq.ContentLength;
stream = fileResp.GetResponseStream();
var resp = HttpContext.Current.Response;
resp.ContentType = fileResp.ContentType;
resp.Cache.SetCacheability(HttpCacheability.Public);
resp.Cache.SetExpires(DateTime.UtcNow.AddHours(maxAgeInHours));
resp.Cache.SetLastModified(DateTime.UtcNow.AddMinutes(-1));
MemoryStream ms = new MemoryStream();
int length;
do
{
if (resp.IsClientConnected)
{
length = stream.Read(buffer, 0, bytesToRead);
resp.OutputStream.Write(buffer, 0, length);
ms.Write(buffer, 0, length);
resp.Flush();
buffer = new Byte[bytesToRead];
}
else
{
length = -1;
}
} while (length > 0); //Repeat until no data is read
}
finally
{
if (stream != null)
{
//Close the input stream
stream.Close();
stream.Dispose();
}
}
With help of this question C# 4.0: Convert pdf to byte[] and vice versa i was able to convert byte[] to PDF. Byte array length is 25990 approx. When i try to open the PDF it says file is corrupted. What could be the reason?
I tried the BinaryWriter but it creates PDF of 0 KB.
It's a response from a Web Service
Sample Code
WebResponse resp = request.GetResponse();
var buffer = new byte[4096];
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(#"E:\sample1.pdf", memoryBuffer);
int s = memoryBuffer.Length;
BinaryWriter binaryWriter = new BinaryWriter(File.Open(#"E:\sample2.pdf", FileMode.Create));
binaryWriter.Write(memoryBuffer);
You are reading twice from the stream but only writing one buffer. Change this:
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, responseStream.Read(buffer, 0, buffer.Length));
To this:
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
It seems your missing some bytes there because you have one unnecessary read. Try this:
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
} while (count != 0);