Uri.AbsolutePath messes up path with spaces - c#

In a WinApp I am simply trying to get the absolute path from a Uri object:
Uri myUri = new Uri(myPath); //myPath is a string
//somewhere else in the code
string path = myUri.AbsolutePath;
This works fine if no spaces in my original path. If spaces are in there the string gets mangled; for example 'Documents and settings' becomes 'Documents%20and%20Setting' etc.
Any help would be appreciated!
EDIT:
LocalPath instead of AbsolutePath did the trick!

This is the way it's supposed to be. That's called URL encoding. It applies because spaces are not allowed in URLs.
If you want the path back with spaces included, you must call something like:
string path = Server.URLDecode(myUri.AbsolutePath);
You shouldn't be required to import anything to use this in a web application. If you get an error, try importing System.Web.HttpServerUtility. Or, you can call it like so:
string path = HttpContext.Current.Server.URLDecode(myUri.AbsolutePath);

It's encoding it as it should, you could probably UrlDecode it to get it back with spaces, but it's not "mangled" it's just correctly encoded.
I'm not sure what you're writing, but to convert it back in asp.net it's Server.UrlDecode(path). You also might be able to use LocalPath, rather than AbsolutePath, if it's a Windows app.

Just use uri.LocalPath instead

Uri also has a couple of static methods - EscapeDataString and EscapeUriString.
Uri.EscapeDataString(uri.AbsolutePath) also works

Use HttpUtility:
HttpUtility.UrlDecode(uri.AbsolutePath)

Related

C# winforms get nth folders from path

I've got an absolute path available to me. Say: C:/Program/CoreFiles/Folder1/Folder2/File.txt.
I need to copy that file to C:/Program/Projects/ProjectName/ but it needs to keep Folder1/Folder2/File.txt intact. So the end result should be C:/Program/Projects/ProjectName/Folder1/Folder2/File.txt.
My first attempt at solving this was to try and get the relative path between 2 absolute paths. Found Path.GetRelativePath(string, string) which obviously didn't help as it wasn't meant for WinForms. It would mess up anyway as the final result would be C:/Program/Projects/ProjectName/CoreFiles/Folder1/Folder2/File.txt.
The target directory is empty and I don't know the relative path to copy beforehand other than somehow getting that info out of the absolute path. Since File.Copy won't create folders that don't exist yet, I need to create them first. So how do I get the path that leads up to the file from the CoreFiles directory out of the absolute path?
The only working solution I can come up with is using regex to just replace CoreFiles with Projects/ProjectName in the path string and work with that. But that somehow seems the wrong approach.
Since you can't use Path.GetRelativePath. I suggest looking at another answer that describes how to do this yourself.
Like here...
How to get relative path from absolute path
Using the method in that answer, you can do the rest of your task as shown below.
string sourcePath = "C:/Program/CoreFiles/Folder1/Folder2/File.txt";
string sourceRoot = "C:/Program/CoreFiles/";
string destinationRoot = "C:/Program/Projects/ProjectName/";
// Use built-in .NET Path.GetRelativePath if you can. Otherwise use a custom function. Like here https://stackoverflow.com/a/340454/1812944
string relativePath = MakeRelativePath(sourceRoot, sourcePath);
// Combine the paths, and make the directory separators all the same.
string destinationPath = Path.GetFullPath(Path.Combine(destinationRoot, relativePath));
// Create nested folder structure for your files.
Directory.CreateDirectory(Path.GetDirectoryName(destinationPath));
// Copy the file over.
File.Copy(sourcePath, destinationPath);

Libragnar(Libtorrent Wrapper) LocalTorrent File, Instead of URL? C#/C++

Question:
Does anyone know how to add a torrent to LibRagnar using a filepath to a torrent, instead of a Url? (LibRagnar is a libtorrent Wrapper)
libragnar = C#
libtorrent = C++
Alternatively if anyone knows How I can use Libtorrent To add the torrent to a session, But use a local file (Whilst still controlling Everything else using Libragnar).But I am not sure where to start with Libtorrent.
Reason For Problem:
I have to use a filepath because the Torrent Requires cookie login to access it. So I either Need to get Libragnar to use a CookieCollection when getting a torrent from a URL or make it use a local ".torrent" file.
Problem:
I am currently trying to use a filepath instead of URL and the Torrent Status gives an error:unsupported URL protocol: D:\Programming\bin\Debug\Tempfiles\File.torrent. Which wont allow me to start it.
Example:
var addParams = new AddTorrentParams
{
SavePath = "C:\\Downloads",
Url = "D:\\Programming\\bin\\Debug\\Tempfiles\\File.torrent"
};
Edit: Answer from Tom W (Posted in C# Chatroom)
var ati = new AddTorrentParams()
{
TorrentInfo = new TorrentInfo("C:\thing.torrent"),
SavePath = #"C:\save\"
};
Note About Answer: I attempted to edit Tom W's post and add the answer he gave me in the Chatroom, However I guess it got declined? But Since he was the one who helped me I wanted him to get credit, and also wanted anyone else having this issue, to have an answer. So I had to add the answer to the bottom of my question.
From the libtorrent documentation it appears that:
The only mandatory parameters are save_path which is the directory
where you want the files to be saved. You also need to specify either
the ti (the torrent file), the info_hash (the info hash of the
torrent) or the url (the URL to where to download the .torrent file
from)
Libragnar's AddTorrentParams appears to be a wrapper around add_torrent_params and has a property called TorrentInfo. I suspect if you avoid setting the URL, and set this property to an instance of TorrentInfo instead, you ought to get the result you want.
Disclaimer: I've never worked with torrents before, don't know this library, and don't work in C++.

Combining System.IO.Path and System.Uri into a complete system path

Im writing a small web interface for my application and am getting hung on combining a known docs path and the request URI into a absolute local path to retrieve the file from.
For simplicity sake I narrowed my code down to the relevant:
string AssemblyDirectory = "C:\MyAppDir\";
string uri = "/index.html";
return new Uri(new Uri(Path.Combine(AssemblyDirectory, "http_docs")), uri).AbsolutePath;
This will always just return the uri portion only; ie the return is "/index.html", it does not seem to like to combine types of Uri and Path properly. I am aware that simply replacing the "/"'s with "\"'s then doing a simple path.combine would work fine, but I cant help but think there is a .net solution to this somewhere that I am overlooking.
The matter is that you have a / before your index.html. It makes the Uri API to refer to the root of the uri, which gives you at last : c:\index.html.
Remove the / in uri to make it work :
string uri = "index.html";

How to get FileName from url

I have url like http://xxx.xxx.xxx/mls/pmmls/12/-8/53/6/12-8536_2.jpg/t1349940727/100x100/
and need to get only filename from url like "12-8536_2.jpg"
url format is dynamic. Filename with extension must be in url. but it filename with extension may not be in last position of url
I have tried Path.GetFileName() but it give "".
is anyone know how extract filename for this type of url?
12-8536_2.jpg does not seem to be a file in that URL. In any case, if the "filename" in the URL will always be in .jpg, you can output the URL to a string (or AS a string) and Regex for it:
string filename = Regex.Match(URL,#"\/([A-Za-z0-9\-._~:?#\[\]#!$%&'()*+,;=]*).jpg").Groups[1].Value
EDIT: I'm thinking this is for a site with different preview sizes for a specific file. You can also specify the different possible extensions as follows (for example):
string filename = Regex.Match(URL,#"\/([A-Za-z0-9\-._~:?#\[\]#!$%&'()*+,;=]*)(.jpg|.JPG|.jpeg|.JPEG)").Groups[1].Value
There is no guarantee that any part of a URL maps to a file, so it does not make sense to try to get the FileName in a URL.
If you know the filename will always be followed by two further segments (in your example, t1349940727 and 100x100), you could do
var input =
"http://xxx.xxx.xxx/mls/pmmls/12/-8/53/6/12-8536_2.jpg/t1349940727/100x100/";
var uri = new Uri(input);
var fileName = uri.Segments[uri.Segments.Length - 3];
If you don't know that, then as others have said, there's no easy way to tell which part is the filename. You could try
var fileName = url.Segments.Last(seg => seg.Contains("."));
to get the last segment with a dot in.
You should define a list of extensions, like .jpg, .png .gif (all files types you are expecting).
Convert your url to string (if it isnt already) and try to find the index of the extension. You do now know the position of the file name and whether there is an file name. remove everything after the file name.
now find a "/" token, and remove the part before (and including) the "/" , repeat this untill you can no longer find "/" (for example with a while function).
more information on how to do this can be found here
static string getFileName(string url) {
string[] arr = url.Split('/');
return arr[arr.Length - 1];
}

move zip file using file.copy()

I am trying to move a file from server \\abc\\C$\\temp\\coll.zip to another server
\\def\\c$\\temp.
I am trying to use File.Copy(source,destination).
But I am getting the error in source path saying: Couldn't find the part of the path.
I am not sure what is wrong with the source path.
You could use a C# # Verbatim and also use checks in the code like this:
string source = #"\\abc\C$\temp\coll.zip";
string destination = #"\\def\c$\temp\coll.zip";
string destDirectory = Path.GetDirectoryName(destination)
if (File.Exists(source) && Directory.Exists(destDirectory)) {
File.Copy(source, destination);
}
else {
// Throw error or alert
}
Make sure that your "\" characters are escaped if you are using C#. You have to double the backslashes or prefix the string literal with #, like this:
string fileName = #"\\abc\C$\temp\coll.zip";
or
string fileName = "\\\\abc\\C$\\temp\\coll.zip";
looks like you need two backslashes at the beginning:
\\abc\C$\temp\coll.zip
\\def\c$\temp
Make sure you are using a valid UNC Path. UNC paths should start with \ not just . You should also consider using System.IO.File.Exists(filename); before attempting the copy so you can avoid the exception altogether and so your app can handle the missing file gracefully.
Hope this helps
It could be the string you are using for the path. If it is exactly as you have entered here I believe you need double backslashes. "\\" before the server name.
I always use network shares for that kind of work, but UNC path's should be available too.
Don't forget that you need to escape your string when you use \'s. Also, UNC paths most of the time start with a double .
Example:
\\MyComputerName\C$\temp\temp.zip
Actually I missed # before the two strings.The source and the destination path.
That is why it was giving error.

Categories

Resources