How to download file in C# with its name? - c#

I'm trying to download file from URL using WebClient, the problem is that the function .DownloadFile() requiring URL, and name that will be given to the saved file, but when we access to the URL it already has the file name.
How can I keep the file name as it is in the URL?

This should work if I understand your question correctly:
private string GetFileNameFromUrl(string url)
{
if(string.IsNullOrEmpty(url))
return "image.jpg"; //or throw an ArgumentException
int sepIndex = url.LastIndexOf("/");
if(sepIndex == -1)
return "image.jpg"; //or throw an ArgumentException
return url.Substring(sepIndex);
}
Then you can use it like so:
string uri = "http://www.mywebsite.com/res/myimage.jpg";
WebClient client = new WebClient();
client.DownloadFile(uri, this.GetFileNameFromUrl(uri));
If you have no control over the url itself you might want to do some validation on it e.g. Regex.

Instead of parsing the url I suggest using function Path.GetFileName():
string uri = "http://yourserveraddress/fileName.txt";
string fileName = System.IO.Path.GetFileName(uri);
WebClient client = new WebClient();
client.DownloadFile(uri, fileName);

What about:
string url = "http://www.mywebsite.com/res/myimage.jpg?guid=2564";
Uri uri = new Uri(url);
string fileName = uri.Segments.Last();
Note: Last() is the extension method from Linq.

Related

How to handle URL having no specific suffix

My Code for Downloader uses two textboxes :
Two get user URL
To specify the drive
private void downloadbtn_Click(object sender, EventArgs e)
{
WebClient myWebClient = new WebClient();
//Declarations for string objects
string downloadURL, path;
//raw URL taken from user
downloadURL = this.downloadURL.Text;
path = savePath.Text;
Uri tmp = new Uri(downloadURL);
string EndPathFileName = tmp.Segments.Last();
path = path + #"\" + EndPathFileName;
//downloads file using async method
myWebClient.DownloadFileAsync(tmp, savePath.Text);
}
The issue arises when i use URL of type:
http://www.dailymotion.com/video/x1coxfe_aryan-khan-tera-pyar-official-music-video-hd_music
which didn't have any suffix i.e. mp3,mp4 etc.
Here it downloads an icon of zero data in the winkle of eye as compared to url having *.mp3/4 etc
Any suggestions please
You should check the Content-Type header not the URL to know the type of file. You can read the content-type like this
string type = client.ResponseHeaders["content-type"];

Get current URL but excluding some parts

The current URL looks like: http://mycompany.com/jobs/java-developer.aspx#.U9-RH2OTLfA
I need to get the part before the #, so it's gonna be: http://mycompany.com/jobs/java-developer.aspx
How can I do that in code behind?
You can use Uri class:
var uri = new Uri("http://mycompany.com/jobs/java-developer.aspx#.U9-RH2OTLfA");
var result = uri.GetLeftPart(UriPartial.Path);
string url = "http://mycompany.com/jobs/java-developer.aspx#.U9-RH2OTLfA";
string path = url.Substring(0, url.IndexOf("#"));
Uri myUri = new Uri("http://mycompany.com/jobs/java-developer.aspx#.U9-RH2OTLfA");
string url = myUri.Host + myUri.LocalPath;
you can create uri with string then get the parts
private String getGoodString(String url)
{
return url.Substring(0, url.IndexOf("#") - 1);
}
This will return everything up to but not including the # symbol in your string. Assuming you have a # to signal when to stop getting the string of the URL. Otherwise if there are multiple #. You can use lastIndexOf, or firstIndexOf if you need to "trim the fat".

URL Formats are not supported

I am reading File with File.OpenRead method, I am giving this path
http://localhost:10001/MyFiles/folder/abc.png
I have tried this as well but no luck
http://localhost:10001//MyFiles//abc.png
but its giving
URL Formats are not supported
When I give physical path of my Drive like this,It works fine
d:\MyFolder\MyProject\MyFiles\folder\abc.png
How can I give file path to an Http path?
this is my code
public FileStream GetFile(string filename)
{
FileStream file = File.OpenRead(filename);
return file;
}
Have a look at WebClient (MSDN docs), it has many utility methods for downloading data from the web.
If you want the resource as a Stream, try:
using(WebClient webClient = new WebClient())
{
using(Stream stream = webClient.OpenRead(uriString))
{
using( StreamReader sr = new StreamReader(stream) )
{
Console.WriteLine(sr.ReadToEnd());
}
}
}
You could either use a WebClient as suggested in other answers or fetch the relative path like this:
var url = "http://localhost:10001/MyFiles/folder/abc.png";
var uri = new Uri(url);
var path = Path.GetFileName(uri.AbsolutePath);
var file = GetFile(path);
// ...
In general you should get rid of the absolute URLs.
The best way to download the HTML is by using the WebClient class. You do this like:
private string GetWebsiteHtml(string url)
{
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string result = reader.ReadToEnd();
stream.Dispose();
reader.Dispose();
return result;
}
Then, If you want to further process the HTML to ex. extract images or links, you will want to use technique known as HTML scrapping.
It's currently best achieved by using the HTML Agility Pack.
Also, documentation on WebClient class: MSDN
Here I found this snippet. Might do exactly what you need:
using(WebClient client = new WebClient()) {
string s = client.DownloadFile(new Uri("http://.../abc.png"), filename);
}
It uses the WebClient class.
To convert a file:// URL to a UNC file name, you should use the Uri.LocalPath property, as documented.
In other words, you can do this:
public FileStream GetFile(string url)
{
var filename = new Uri(url).LocalPath;
FileStream file = File.OpenRead(filename);
return file;
}

webclient or httpwebrequest to retrieve hrefs and url

How do I use either webclient or httpwebrequest to do two things:
1)Say after downloading the resource as a string using:
var result = x.DownloadString("http://randomsite.com);
there's a relative url(also query string):
Click here to get your name and age
how do I click(follow) on that link using webclient? after initially loading the resource in result. i was able to use htmlagilitypack to isolate the href but I would now like to follow it in code.
2) If the httpwebrequest does not redirect but instead loads the same page with different parameters how would i use webclient to retrieve the new url that is generated?
i.e if i call
var result = x.DownloadString("http://randomsite.com);
but this actually calls
http://randomsite.com/q?site=default
I then want to retrieve the second url
Thanks in advance
You can construct the url from the link and the link that you just downloaded like this:
Uri baseUri = new Uri("http://randomsite.com");
Uri myUri = new Uri(baseUri, "/q?name=john&age=50");
Console.WriteLine(myUri.ToString()); // gives you http://randomsite.com/q?name=john&age=50
This also works if you base Url has url parameters.
As for the second question, i guess you meant that the request was redirected and you want that url instead? Then the easiest way to do so is to sub-class WebClient described here.
Uri baseUri = new Uri("http://randomsite.com");
using(var client=new WebClient())
{
var result = client.DownloadString(myUri);
//get href via HtmlAgilityPack...
Uri myUri = new Uri(baseUri, "/q?name=john&age=50");
result = client.DownloadString(myUri);
}

Howto: download a file keeping the original name in C#?

I have files on a server that can be accessed from a URL formatted like this:
http:// address/Attachments.aspx?id=GUID
I have access to the GUID and need to be able to download multiple files to the same folder.
if you take that URL and throw it in a browser, you will download the file and it will have the original file name.
I want to replicate that behavior in C#. I have tried using the WebClient class's DownloadFile method, but with that you have to specify a new file name. And even worse, DownloadFile will overwrite an existing file. I know I could generate a unique name for every file, but i'd really like the original.
Is it possible to download a file preserving the original file name?
Update:
Using the fantastic answer below to use the WebReqest class I came up with the following which works perfectly:
public override void OnAttachmentSaved(string filePath)
{
var webClient = new WebClient();
//get file name
var request = WebRequest.Create(filePath);
var response = request.GetResponse();
var contentDisposition = response.Headers["Content-Disposition"];
const string contentFileNamePortion = "filename=";
var fileNameStartIndex = contentDisposition.IndexOf(contentFileNamePortion, StringComparison.InvariantCulture) + contentFileNamePortion.Length;
var originalFileNameLength = contentDisposition.Length - fileNameStartIndex;
var originalFileName = contentDisposition.Substring(fileNameStartIndex, originalFileNameLength);
//download file
webClient.UseDefaultCredentials = true;
webClient.DownloadFile(filePath, String.Format(#"C:\inetpub\Attachments Test\{0}", originalFileName));
}
Just had to do a little string manipulation to get the actual filename. I'm so excited. Thanks everyone!
As hinted in comments, the filename will be available in Content-Disposition header. Not sure about how to get its value when using WebClient, but it's fairly simple with WebRequest:
WebRequest request = WebRequest.Create("http://address/Attachments.aspx?id=GUID");
WebResponse response = request.GetResponse();
string originalFileName = response.Headers["Content-Disposition"];
Stream streamWithFileBody = response.GetResponseStream();

Categories

Resources