This repository was archived by the owner on Dec 6, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 98
This repository was archived by the owner on Dec 6, 2024. It is now read-only.
ExtensionMethod FileSystemInfo.ToUrl(..) #305
Copy link
Copy link
Open
Labels
Description
I made an extension method that correctly converts a file path into a file url and returns it as URI. If you are interested in, feel free to implement it somehow...
using System;
using System.ComponentModel;
using System.IO;
using System.Text;
/// <summary>Defines an extension method called <see cref="ToUrl" /> for <see cref="FileInfo" /> and <see cref="DirectoryInfo" />
/// objects to retrieve their file URL (e.g. "file:///c:/foo/bar.txt").</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
internal static class Ext_FileSystemInfo_ToUrl {
//Public Extension Methods
/// <summary>Converts the path of a file or folder into a file URL (e.g. "file:///c:/foo/bar.txt").</summary>
/// <param name="fileOrFolder">The file or folder whose URL to return.</param>
/// <returns>The properly escaped URL (you can call <see cref="Uri.LocalPath" /> on it to revert to the original file path, e.g. "C:\foo\bar.txt").</returns>
/// <exception cref="System.NullReferenceException">A <see cref="NullReferenceException" /> (not an <see cref="ArgumentNullException" />!) is thrown if the given file or folder is null, to simulate instance method behavior.</exception>
/// <exception cref="System.FormatException">A <see cref="NullReferenceException" /> (not an <see cref="ArgumentNullException" />!) is thrown if the given file or folder is null, to simulate instance method behavior.</exception>
public static Uri ToUrl(this FileSystemInfo fileOrFolder) {
//Check args (simulate instance method behavior)
if (Object.ReferenceEquals(fileOrFolder, null)) throw new NullReferenceException();
//Convert absolute path to file or folder
String myFileUri = FilePathToFileUrl(fileOrFolder.FullName);
Uri myResult = new Uri(myFileUri);
//Return the result
return myResult;
}
//Private Methods
/// <summary>Converts a file path into a properly escaped file URI (e.g. "C:\foo, bar\Alice%33.txt" -> "file:///C:/foo%2C%20bar/Alice%2533.txt").
/// It intentionally does not use classes <see cref="Uri" /> nor <see cref="UriBuilder" /> for the escaping as they are rather buggy.</summary>
/// <param name="filePath">The absolute path to the file or folder.</param>
/// <returns>A properly escaped file URI.</returns>
/// <exception cref="System.ArgumentNullException">An ArgumentNullException is thrown if the path is null or white-space.</exception>
private static String FilePathToFileUrl(String filePath) {
//Credits to poizan42 from http://stackoverflow.com/users/1555496/poizan42 who provided the logic this method is based on (MIT licensed).
if (String.IsNullOrWhiteSpace(filePath)) throw new ArgumentNullException(nameof(filePath));
StringBuilder myResult = new StringBuilder((Int32)(filePath.Length * 1.2) + 8); //Assumes that every 10th character must be escaped with 2 additional chars
Char myDirectorySeparatorChar = '\\'; //Path.DirectorySeparatorChar
Char myAltDirectorySeparatorChar = '/'; //Path.AltDirectorySeparatorChar
String myOtherValidChars = ".+-_:~";
foreach (Char c in filePath) {
//Check whether it is a letter or digit or above ASC 255
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c > '\xFF')) {
myResult.Append(c);
continue;
}
//Check whether it is a directory separator
if ((c == myDirectorySeparatorChar) || (c == myAltDirectorySeparatorChar)) {
myResult.Append('/');
continue;
}
//Check whether it is a valid sign
if (myOtherValidChars.IndexOf(c) > -1) {
myResult.Append(c);
continue;
}
//Otherwise escape it
myResult.AppendFormat("%{0:X2}", (int)c);
}
//Append prefix (UNC vs. ordinary path)
String myPrefix = (myResult.Length >= 2 && myResult[0] == '/' && myResult[1] == '/') ? "file:" : "file:///";
myResult.Insert(0, myPrefix);
//Return result
return myResult.ToString();
}
}
Yomodo