I wrote a program to download files from a website by using WebClient.DownloadFile().
public static void downWeb()
{
WebClient myWebClient = new WebClient();
path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
if (add() == 1)
{
Console.WriteLine("Response is " + add());
Console.WriteLine("Downloading File = " + dynFileName + "....");
myWebClient.DownloadFile(fullAddress, (path + dynFileName));
}
}
public static int add()
{
string url = fullAddress;
WebRequest webRequest = WebRequest.Create(url);
WebResponse webResponse;
try
{
webResponse = webRequest.GetResponse();
}
catch
{
return 0;
}
return 1;
}
downWeb() is a function to be called in the Main() function.
add() is a function that tests the availability of the file on server. If response is positive, it returns value "1".
fullAddress = address from where the files has to downloaded. It's changing every time before calling this function in a loop present in Main().
When I start my application, I ask the user to:
1) Enter URL to be downloaded i.e. www.1234.com\samplefiles\pg-1.pdf
2) Number of pages to be downloaded (By changing the above filename no. in a loop as rest of the url is same on server)
Now my problem is when I am downloading files, first file downloads PERFECTLY, but the second download is never finished. It says "REQUEST TIMED OUT", and my application closes.
I don't know what's happening here.
How can this be solved?
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse.aspx
You must call the Close method to close the stream and release the connection. Failure to do so may cause your application to run out of connections.
Your problem likely is related to the fact that you do not dispose of your connections. You should make sure that you don't leak them.
Related
I can connect to the Azure Storage account and can even upload a file, but when I go to download the file using DownloadToFileAsync() I get a 0kb file as a result.
I have checked and the "CloudFileDirectory" and the "CloudFile" fields are all correct, which means the connection with Azure is solid. I can even write the output from the file to the console, but I cannot seem to save it as a file.
public static string PullFromAzureStorage(string azureFileConn, string remoteFileName, string clientID)
{
var localDirectory = #"C:\cod\clients\" + clientID + #"\ftp\";
var localFileName = clientID + "_xxx_" + remoteFileName;
//Retrieve storage account from connection string
var storageAccount = CloudStorageAccount.Parse(azureFileConn);
var client = storageAccount.CreateCloudFileClient();
var share = client.GetShareReference("testing");
// Get a reference to the root directory for the share
CloudFileDirectory rootDir = share.GetRootDirectoryReference();
//Get a ref to client folder
CloudFileDirectory cloudFileDirectory = rootDir.GetDirectoryReference(clientID);
// Get a reference to the directory we created previously
CloudFileDirectory unprocessed = cloudFileDirectory.GetDirectoryReference("Unprocessed");
// Get a reference to the file
CloudFile sourceFile = unprocessed.GetFileReference(remoteFileName);
//write to console and log
Console.WriteLine("Downloading file: " + remoteFileName);
LogWriter.LogWrite("Downloading file: " + remoteFileName);
//Console.WriteLine(sourceFile.DownloadTextAsync().Result);
sourceFile.DownloadToFileAsync(Path.Combine(localDirectory, localFileName), FileMode.Create);
//write to console and log
Console.WriteLine("Download Successful!");
LogWriter.LogWrite("Download Successful!");
//delete remote file after download
//sftp.DeleteFile(remoteDirectory + remoteFileName);
return localFileName;
}
In the commented out line of code where you write the output to the Console, you explicitly use .Result because you're calling an async method in a synchronous one. You should either also do so while downloading the file as well, or make the entire method around it async.
The first solution would look something like this:
sourceFile.DownloadToFileAsync(Path.Combine(localDirectory, localFileName), FileMode.Create).Result();
EDIT:
As far as the difference with the comment, that uses GetAwaiter().GetResult(), goes: .Result wraps any exception that might occur in an AggregateException, while GetAwaiter().GetResult() won't. Anyhow: if there's any possibility you can refactor the method to be async so you can use await: please do so.
I'm trying to download a simple xml file and save it to the users local profile. When trying to download (i don't think this has anything to do with the saving location but i'm not 100% sure) i get the following exception on the webclient.
System.InvalidOperationException
My code is as follows;
public void downloadProxy() {
string url = Properties.Settings.Default.url;
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "/netsettings/proxies.xml");
try
{
WebClient GrabFile = new WebClient();
GrabFile.DownloadFile(url, path);
}
catch (WebException webEx)
{
if (webEx.Status == WebExceptionStatus.ConnectFailure)
{
Console.WriteLine("Are you behind a firewall? If so, go through the proxy server.");
}
}
}
If you are on a Windows operating system, use a backslash (not a slash) as folder separator:
\netsettings\proxies.xml
I am attempting to download a file from another IIS site on my local machine. I have my main website that is trying to download from another public site that contains a few files that the user will be able to download.
[HttpGet]
public ActionResult DownloadMyPrintManagerInstaller()
{
bool success;
try
{
using (var client = new WebClient())
{
client.DownloadFile(new Uri("http://localhost:182//MyPrintInstaller.exe"), "MyPrintManager.exe");
}
success = true;
}
catch (Exception)
{
success = false;
}
return Json(new { Success = success }, JsonRequestBehavior.AllowGet);
}
For some reason, it is attempting to download the file from C:\windows\system32\inetsrv\MyPrintManager.exe? Does anyone know how I can avoid it from pointing to that directory? Do I need to modify my code or my IIS configuration?
My virtual directory for this site is a folder sitting on my C: drive, and the file I actually want to download is in that directory.
No, it's attempting to save the file to C:\windows\system32\inetsrv\MyPrintManager.exe.
That's because C:\windows\system32\inetsrv is the working directory for your process, and you've just given a relative filename.
Specify an absolute filename which says exactly where you want the file to be stored, and it should be fine.
WebClient web = new WebClient();
string url = "http://.../FILENAME.jpg";
web.DownloadFile(new Uri(url), "C:/FILENAME.jpg");
I am creating a file on ftp server. But Before creating file on server I also check that it does not existing already. However, It is working fine most of the system but one of my client has problem. When he run the application, it throws the system.formatexception i-e input string is not in correct format.
I am unable to understand this problem. Can anybody help me?
The following is the code to create file.
public string createFile(string filename1)
{
StreamWriter sw1 = null;
System.Net.FtpWebRequest tmpReq1;
try
{
tmpReq1 = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create("ftp://ftp.dunyameri.com/pt/" + filename1);
tmpReq1.Credentials = new System.Net.NetworkCredential("naveed#dunyameri.com", "xxxxx");
FtpWebResponse response = (FtpWebResponse)tmpReq1.GetResponse();
}
catch (WebException ex)
{
FtpWebResponse response2 = (FtpWebResponse)ex.Response;
if (response2.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
{
// I am creating file here
}
else
{
return ex.ToString();
}
}
return "File Created";
}
I haves searched on internet that it might be because of string contain 0 or dots. In this particular system case the file name contain dots and 0. Is it because of this type of file name?
Thanks,
Naveed
It seems that the error does not occur within "createFile(string filename1)". If so, the stack should be similar to this:
...
System.Convert.ToInt32(String value)
e2erta.e2erta1.YourFtpClass.createFile(string filename1) <- I would expect this line!
e2erta.e2erta1..ctor()
My best guess would be that filename1 starts with a / character. You can use the Path.Combine method to handle this case:
var path = Path.Combine("ftp://ftp.dunyameri.com/pt/", filename1);
var tmpReq1 = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create(path);
...
Url should be something like "ftp://" + userName + ":" + password + "#" + serverAddress + ":" + serverPort + "/" + file.
Try to add port.
The class FtpWebRequest does not have a Create method seelink http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest_methods
The example shown on link casts WebRequest.Create to FtpWebRequest this might be the issue
I can't seem to find a solution to this issue. I'm trying to get my Compact Framework application on Windows Mobile 6 to have the ability to move a file on its local filesystem to another system.
Here's the solutions I'm aware of:
FTP - Problem with that is most of
the APIs are way to expensive to use.
HTTP PUT - As far as I have been able to find, I can't use anonymous PUT with IIS7, and that's the web server the system is running. (An extreme workaround for this would be to use a different web server to PUT the file, and have that other system transfer it to the IIS system).
Windows share - I would need authentication on the shares, and I haven't seen that a way to pass this authentication through windows mobile.
The last resort would be to require that the devices be cradled to transfer these files, but I'd really like to be able to have these files be transferred wirelessly.
FTP: define "too expensive". Do you mean performance or byte overhead or dollar cost? Here's a free one with source.
HTTP: IIS7 certainly supports hosting web services or custom IHttpHandlers. You could use either for a data upload pretty easily.
A Windows Share simply requires that you to P/Invoke the WNet APIs to map the share, but it's not terribly complex.
I ended up just passing information to a web server via a PHP script.
The options provided above just didn't work out for my situation.
Here's the gist of it. I've got some code in there with progress bars and various checks and handlers unrelated to simply sending a file, but I'm sure you can pick through it. I've removed my authentication code from both the C# and the PHP, but it shouldn't be too hard to roll your own, if necessary.
in C#:
/*
* Here's the short+sweet about how I'm doing this
* 1) Copy the file from mobile device to web server by querying PHP script with paramaters for each line
* 2) PHP script checks 1) If we got the whole data file 2) If this is a duplicate data file
* 3) If it is a duplicate, or we didn't get the whole thing, it goes away. The mobile
* device will hang on to it's data file in the first case (if it's duplicate it deletes it)
* to be tried again later
* 4) The server will then process the data files using a scheduled task/cron job at an appropriate time
*/
private void process_attempts()
{
Uri CheckUrl = new Uri("http://path/to/php/script?action=check");
WebRequest checkReq = WebRequest.Create(CheckUrl);
try
{
WebResponse CheckResp = checkReq.GetResponse();
CheckResp.Close();
}
catch
{
MessageBox.Show("Error! Connection not available. Please make sure you are online.");
this.Invoke(new Close(closeme));
}
StreamReader dataReader = File.OpenText(datafile);
String line = null;
line = dataReader.ReadLine();
while (line != null)
{
Uri Url = new Uri("http://path/to/php/script?action=process&line=" + line);
WebRequest WebReq = WebRequest.Create(Url);
try
{
WebResponse Resp = WebReq.GetResponse();
Resp.Close();
}
catch
{
MessageBox.Show("Error! Connection not available. Please make sure you are online.");
this.Invoke(new Close(closeme));
return;
}
try
{
process_bar.Invoke(new SetInt(SetBarValue), new object[] { processed });
}
catch { }
process_num.Invoke(new SetString(SetNumValue), new object[] { processed + "/" + attempts });
processed++;
line = dataReader.ReadLine();
}
dataReader.Close();
Uri Url2 = new Uri("http://path/to/php/script?action=finalize&lines=" + attempts);
Boolean finalized = false;
WebRequest WebReq2 = WebRequest.Create(Url2);
try
{
WebResponse Resp = WebReq2.GetResponse();
Resp.Close();
finalized = true;
}
catch
{
MessageBox.Show("Error! Connection not available. Please make sure you are online.");
this.Invoke(new Close(closeme));
finalized = false;
}
MessageBox.Show("Done!");
this.Invoke(new Close(closeme));
}
In PHP (thoroughly commented for your benefit!):
<?php
//Get the GET'd values from the C#
//The current line being processed
$line = $_GET['line'];
//Which action we are doing
$action = $_GET['action'];
//# of lines in the source file
$totalLines = $_GET['lines'];
//If we are processing the line, open the data file, and append this new line and a newline.
if($action == "process"){
$dataFile = "tempdata/SOME_KIND_OF_UNIQUE_FILENAME.dat";
//open the file
$fh = fopen($dataFile, 'a');
//Write the line, and a newline to the file
fwrite($fh, $line."\r\n");
//Close the file
fclose($fh);
//Exit the script
exit();
}
//If we are done processing the original file from the C# application, make sure the number of lines in the new file matches that in the
//file we are transferring. An expansion of this could be to compare some kind of hash function value of both files...
if($action == "finalize"){
$dataFile = "tempdata/SOME_KIND_OF_UNIQUE_FILENAME.dat";
//Count the number of lines in the new file
$lines = count(file($dataFile));
//If the new file and the old file have the same number of lines...
if($lines == $totalLines){
//File has the matching number of lines, good enough for me over TCP.
//We should move or rename this file.
}else{
//File does NOT have the same number of lines as the source file.
}
exit();
}
if($action == "check"){
//If a file with this unique file name already exists, delete it.
$dataFile = "tempdata/SOME_KIND_OF_UNIQUE_FILENAME.dat";
if(file_exists($dataFile)){
unlink($dataFile);
}
}
?>