2 /* -----------------------------------------------------------------------
3 * <copyright file="FileInfoExtensions.cs" company="GRNet">
5 * Copyright 2011-2012 GRNET S.A. All rights reserved.
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
11 * 1. Redistributions of source code must retain the above
12 * copyright notice, this list of conditions and the following
15 * 2. Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials
18 * provided with the distribution.
21 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * The views and conclusions contained in the software and
35 * documentation are those of the authors and should not be
36 * interpreted as representing official policies, either expressed
37 * or implied, of GRNET S.A.
39 * -----------------------------------------------------------------------
43 using System.Collections.Generic;
44 using System.Diagnostics.Contracts;
48 using System.Text.RegularExpressions;
49 using System.Threading.Tasks;
52 namespace Pithos.Interfaces
54 public static class FileInfoExtensions
56 public static string AsRelativeTo(this FileSystemInfo fileInfo,string path )
58 if (String.IsNullOrWhiteSpace(path))
59 throw new ArgumentNullException("path");
60 Contract.EndContractBlock();
61 Contract.Assume(Enum.IsDefined(typeof(StringComparison),StringComparison.InvariantCultureIgnoreCase));
63 if (!path.EndsWith("\\"))
64 path=path.ToLower() + "\\";
65 int pathLength = path.Length;
67 var filePath = fileInfo.GetProperCapitalization();
69 if (!filePath.StartsWith(path,StringComparison.InvariantCultureIgnoreCase))
70 throw new ArgumentException(String.Format("The path {0} doesn't contain the file {1}",path,filePath));
72 var relativePath = filePath.Substring(pathLength, filePath.Length - pathLength);
77 public static string AsRelativeUrlTo(this FileSystemInfo fileInfo,string path )
79 if (String.IsNullOrWhiteSpace(path))
80 throw new ArgumentNullException("path");
81 Contract.EndContractBlock();
83 var relativePath = fileInfo.AsRelativeTo(path);
84 var replacedSlashes = relativePath.Replace("\\","/");
85 var escaped = Uri.EscapeUriString(replacedSlashes);
89 public static string RelativeUriToFilePath(this Uri uri)
91 var unescaped = Uri.UnescapeDataString(uri.ToString());
92 var path = unescaped.Replace("/", "\\");
97 public static string GetProperDirectoryCapitalization(string fileName)
99 Contract.Ensures(!String.IsNullOrWhiteSpace(Contract.Result<string>()));
100 Contract.EndContractBlock();
102 if (String.IsNullOrWhiteSpace(fileName))
105 var dirInfo = new DirectoryInfo(fileName);
106 return dirInfo.GetProperCapitalization();
110 public static string GetProperCapitalization(this DirectoryInfo dirInfo)
113 throw new ArgumentNullException("dirInfo");
114 Contract.EndContractBlock();
115 Contract.Assume(!String.IsNullOrWhiteSpace(dirInfo.FullName));
117 var parentDirInfo = dirInfo.Parent;
118 if (null == parentDirInfo)
126 return Path.Combine(GetProperDirectoryCapitalization(parentDirInfo.FullName),
127 parentDirInfo.GetDirectories(dirInfo.Name)[0].Name);
130 return dirInfo.FullName;
133 catch (DirectoryNotFoundException)
135 //An exception can occur if a directory is deleted right after the Exists call
136 return dirInfo.FullName;
141 public static string GetProperFilePathCapitalization(string fileName)
143 Contract.Ensures(!String.IsNullOrWhiteSpace(Contract.Result<string>()));
144 Contract.EndContractBlock();
145 if (String.IsNullOrWhiteSpace(fileName))
149 var fileInfo = new FileInfo(fileName);
150 return fileInfo.GetProperCapitalization();
153 public static string GetProperCapitalization(this FileInfo fileInfo)
155 if (fileInfo == null)
156 throw new ArgumentNullException("fileInfo");
157 Contract.EndContractBlock();
160 var dirInfo = fileInfo.Directory;
162 //Directory will not be null for an absolute path
163 Contract.Assume(dirInfo != null);
167 //Exists returns a cached value that can be true even if a file was deleted since the
168 //FileInfo object was created.
171 return Path.Combine(GetProperDirectoryCapitalization(dirInfo.FullName),
172 dirInfo.GetFiles(fileInfo.Name)[0].Name);
175 return fileInfo.FullName;
178 catch (FileNotFoundException)
180 //An exception can occur if a file is deleted right after the Exists call
181 return fileInfo.FullName;
186 public static string GetProperCapitalization(this FileSystemInfo info)
188 if (info is FileInfo)
189 return (info as FileInfo).GetProperCapitalization();
190 if (info is DirectoryInfo)
191 return (info as DirectoryInfo).GetProperCapitalization();
192 throw new NotSupportedException("Unexpected parameter type");
195 public static DirectoryInfo WithProperCapitalization(this DirectoryInfo dirInfo)
198 throw new ArgumentNullException("dirInfo");
199 Contract.EndContractBlock();
201 var path = dirInfo.GetProperCapitalization();
202 return new DirectoryInfo(path);
205 public static FileInfo WithProperCapitalization(this FileInfo fileInfo)
208 throw new ArgumentNullException("fileInfo");
209 Contract.EndContractBlock();
211 var path = fileInfo.GetProperCapitalization();
212 return new FileInfo(path);
215 public static FileSystemInfo WithProperCapitalization(this FileSystemInfo info)
218 throw new ArgumentNullException("info");
219 Contract.EndContractBlock();
221 if (info is FileInfo)
222 return (info as FileInfo).WithProperCapitalization();
223 if (info is DirectoryInfo)
224 return (info as DirectoryInfo).WithProperCapitalization();
226 throw new NotSupportedException("Unexpected parameter type");
229 public static FileSystemInfo FromPath(string filePath)
231 if (String.IsNullOrWhiteSpace(filePath))
232 throw new ArgumentNullException("filePath");
233 Contract.EndContractBlock();
235 return Directory.Exists(filePath) ?
236 (FileSystemInfo) new DirectoryInfo(filePath)
237 : new FileInfo(filePath);