Directory.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. //
  2. // System.IO.Directory.cs
  3. //
  4. // Authors:
  5. // Jim Richardson ([email protected])
  6. // Miguel de Icaza ([email protected])
  7. // Dan Lewis ([email protected])
  8. // Eduardo Garcia ([email protected])
  9. //
  10. // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
  11. // Copyright (C) 2002 Ximian, Inc.
  12. //
  13. // Created: Monday, August 13, 2001
  14. //
  15. //------------------------------------------------------------------------------
  16. using System;
  17. using System.Security.Permissions;
  18. using System.Collections;
  19. using System.Text;
  20. namespace System.IO
  21. {
  22. public sealed class Directory : Object
  23. {
  24. private Directory () {}
  25. public static DirectoryInfo CreateDirectory (string path)
  26. {
  27. DirectoryInfo tmpinfo = null;
  28. if (path == null) {
  29. throw new ArgumentNullException ("path");
  30. }
  31. if (path == "") {
  32. throw new ArgumentException ("Path is empty");
  33. }
  34. if (path.IndexOfAny (Path.InvalidPathChars) != -1) {
  35. throw new ArgumentException ("Path contains invalid chars");
  36. }
  37. if (path.Trim().Length == 0){
  38. throw new ArgumentException ("Only blank characters in path");
  39. }
  40. if (path == ":")
  41. throw new NotSupportedException ("Only ':' In path");
  42. string[] pathcomponents = path.Split(new char[] { Path.DirectorySeparatorChar });
  43. if (pathcomponents.Length == 1){
  44. tmpinfo = Directory.RealCreateDirectory(path);
  45. return tmpinfo;
  46. }
  47. else {
  48. if ((path[0]== Path.DirectorySeparatorChar) ||
  49. ((path[1] == ':') && (path[2] == Path.DirectorySeparatorChar))) //Absolute Path
  50. {
  51. //Should Work in Unix, Win* native Directoryes and Samba Shares
  52. //FIXME: This is not thread safe
  53. string actual_path = Directory.GetCurrentDirectory();
  54. if (Environment.OSVersion.Platform == PlatformID.Unix) //Is Unix
  55. {
  56. StringBuilder pathsumm = new StringBuilder(path);
  57. Directory.SetCurrentDirectory ("/");
  58. pathsumm.Remove (0,1);
  59. tmpinfo = Directory.CreateDirectory(pathsumm.ToString());
  60. }
  61. else //We asume is Win*
  62. {
  63. if ((path[1] == ':') || (path[0] == Path.DirectorySeparatorChar)) //Is a regular path
  64. {
  65. StringBuilder pathsumm = new StringBuilder(path);
  66. Directory.SetCurrentDirectory(path.Substring(0,2));
  67. pathsumm.Remove(0,2);
  68. tmpinfo = Directory.CreateDirectory(pathsumm.ToString());
  69. }
  70. else if((path[0] == '\\') && (path[1] == '\\')) //Is a Samba Share
  71. {
  72. if (Directory.Exists(pathcomponents[0] + "\\"
  73. + pathcomponents[1] + "\\"
  74. + pathcomponents[2]))
  75. {
  76. StringBuilder pathsumm = new StringBuilder();
  77. Directory.SetCurrentDirectory(pathcomponents[0] +
  78. "\\" + pathcomponents[1] +
  79. "\\" + pathcomponents[2] +
  80. "\\" + pathcomponents[3]);
  81. pathcomponents[0] = ""; pathcomponents[1] = ""; pathcomponents[2] = "";
  82. pathcomponents[3] = "";
  83. foreach(string dir in pathcomponents)
  84. {
  85. if (dir != "")
  86. pathsumm.Append(dir + "\\");
  87. }
  88. Directory.CreateDirectory(pathsumm.ToString());
  89. }
  90. else
  91. {
  92. throw new DirectoryNotFoundException("The samba share do not Exists");
  93. }
  94. }
  95. }
  96. Directory.SetCurrentDirectory(actual_path);
  97. }
  98. else //Relative Path
  99. {
  100. StringBuilder pathsumm = new StringBuilder();
  101. foreach(string dir in pathcomponents)
  102. {
  103. if (dir.Length != 0) {
  104. if (pathsumm.Length == 0) {
  105. pathsumm.Append (dir);
  106. }
  107. else {
  108. pathsumm.Append (Path.DirectorySeparatorChar + dir);
  109. }
  110. if (!Directory.Exists (pathsumm.ToString())) {
  111. tmpinfo = Directory.RealCreateDirectory (pathsumm.ToString());
  112. }
  113. }
  114. }
  115. }
  116. }
  117. return tmpinfo;
  118. }
  119. private static DirectoryInfo RealCreateDirectory (string path)
  120. {
  121. MonoIOError error;
  122. if (!MonoIO.CreateDirectory (path, out error)) {
  123. throw MonoIO.GetException (error);
  124. }
  125. return new DirectoryInfo (path);
  126. }
  127. public static void Delete (string path)
  128. {
  129. if (path == null) {
  130. throw new ArgumentNullException ("path");
  131. }
  132. if (path == "") {
  133. throw new ArgumentException ("Path is empty");
  134. }
  135. if (path.IndexOfAny (Path.InvalidPathChars) != -1) {
  136. throw new ArgumentException ("Path contains invalid chars");
  137. }
  138. if (path.Trim().Length == 0)
  139. throw new ArgumentException ("Only blank characters in path");
  140. if (path == ":")
  141. throw new NotSupportedException ("Only ':' In path");
  142. MonoIOError error;
  143. if (!MonoIO.RemoveDirectory (path, out error)) {
  144. throw MonoIO.GetException (error);
  145. }
  146. }
  147. static void RecursiveDelete (string path)
  148. {
  149. foreach (string dir in GetDirectories (path))
  150. RecursiveDelete (dir);
  151. foreach (string file in GetFiles (path))
  152. File.Delete (file);
  153. Directory.Delete (path);
  154. }
  155. public static void Delete (string path, bool recurse)
  156. {
  157. if (path == null)
  158. throw new ArgumentNullException ();
  159. if (path == "")
  160. throw new System.ArgumentException("Path is Empty");
  161. if (path.IndexOfAny (Path.InvalidPathChars) != -1)
  162. throw new ArgumentException ("Path contains invalid characters");
  163. if (path.Trim().Length == 0)
  164. throw new ArgumentException ("Only blank characters in path");
  165. if (path == ":")
  166. throw new NotSupportedException ("Only ':' In path");
  167. if (recurse == false){
  168. Delete (path);
  169. return;
  170. }
  171. RecursiveDelete (path);
  172. }
  173. public static bool Exists (string path)
  174. {
  175. if (path == null)
  176. return false;
  177. MonoIOError error;
  178. return MonoIO.ExistsDirectory (path, out error);
  179. }
  180. public static DateTime GetLastAccessTime (string path)
  181. {
  182. return File.GetLastAccessTime (path);
  183. }
  184. public static DateTime GetLastWriteTime (string path)
  185. {
  186. return File.GetLastWriteTime (path);
  187. }
  188. public static DateTime GetCreationTime (string path)
  189. {
  190. if (path == null)
  191. throw new System.ArgumentNullException("Path is Null");
  192. if (path == "")
  193. throw new System.ArgumentException("Path is Empty");
  194. if (path.Trim().Length == 0)
  195. throw new ArgumentException ("Only blank characters in path");
  196. if (path.IndexOfAny (Path.InvalidPathChars) != -1)
  197. throw new ArgumentException ("Path contains invalid chars");
  198. if (path == ":")
  199. throw new NotSupportedException ("Only ':' In path");
  200. return File.GetLastWriteTime (path);
  201. }
  202. public static string GetCurrentDirectory ()
  203. {
  204. /*
  205. // Implementation complete 08/25/2001 14:24 except for
  206. // LAMESPEC: documentation specifies invalid exceptions (i think)
  207. // also shouldn't need Write to getcurrrent should we?
  208. string str = Environment.CurrentDirectory;
  209. CheckPermission.Demand (FileIOPermissionAccess.Read & FileIOPermissionAccess.Write, str);
  210. */
  211. return Environment.CurrentDirectory;
  212. }
  213. public static string [] GetDirectories (string path)
  214. {
  215. return GetDirectories (path, "*");
  216. }
  217. public static string [] GetDirectories (string path, string pattern)
  218. {
  219. return GetFileSystemEntries (path, pattern, FileAttributes.Directory, FileAttributes.Directory);
  220. }
  221. public static string GetDirectoryRoot (string path)
  222. {
  223. return new String(Path.DirectorySeparatorChar,1);
  224. }
  225. public static string [] GetFiles (string path)
  226. {
  227. return GetFiles (path, "*");
  228. }
  229. public static string [] GetFiles (string path, string pattern)
  230. {
  231. return GetFileSystemEntries (path, pattern, FileAttributes.Directory, 0);
  232. }
  233. public static string [] GetFileSystemEntries (string path)
  234. {
  235. return GetFileSystemEntries (path, "*");
  236. }
  237. public static string [] GetFileSystemEntries (string path, string pattern)
  238. {
  239. if (path == null)
  240. throw new ArgumentNullException ();
  241. if (path.IndexOfAny (Path.InvalidPathChars) != -1)
  242. throw new ArgumentException ("Path contains invalid characters");
  243. if (path == "")
  244. throw new ArgumentException ("The Path do not have a valid format");
  245. return GetFileSystemEntries (path, pattern, 0, 0);
  246. }
  247. public static string[] GetLogicalDrives ()
  248. {
  249. //FIXME: Hardcoded Paths
  250. if (Environment.OSVersion.Platform == PlatformID.Unix)
  251. return new string[] { "/" };
  252. else
  253. return new string [] { "A:\\", "C:\\" };
  254. }
  255. public static DirectoryInfo GetParent (string path)
  256. {
  257. if (path == null)
  258. throw new ArgumentNullException ();
  259. if (path.IndexOfAny (Path.InvalidPathChars) != -1)
  260. throw new ArgumentException ("Path contains invalid characters");
  261. if (path == "")
  262. throw new ArgumentException ("The Path do not have a valid format");
  263. return new DirectoryInfo (Path.GetDirectoryName (path + Path.DirectorySeparatorChar + ".."));
  264. }
  265. public static void Move (string src, string dest)
  266. {
  267. File.Move (src, dest);
  268. }
  269. public static void SetCreationTime (string path, DateTime creation_time)
  270. {
  271. File.SetCreationTime (path, creation_time);
  272. }
  273. public static void SetCurrentDirectory (string path)
  274. {
  275. /*
  276. // Implementation complete 08/25/2001 14:24 except for
  277. // LAMESPEC: documentation specifies invalid exceptions IOException (i think)
  278. CheckArgument.Path (path, true);
  279. CheckPermission.Demand (FileIOPermissionAccess.Read & FileIOPermissionAccess.Write, path);
  280. */
  281. if (!Exists (path))
  282. {
  283. throw new DirectoryNotFoundException ("Directory \"" + path + "\" not found.");
  284. }
  285. Environment.CurrentDirectory = path;
  286. }
  287. public static void SetLastAccessTime (string path, DateTime last_access_time)
  288. {
  289. File.SetLastAccessTime (path, last_access_time);
  290. }
  291. public static void SetLastWriteTime (string path, DateTime last_write_time)
  292. {
  293. File.SetLastWriteTime (path, last_write_time);
  294. }
  295. // private
  296. private static string [] GetFileSystemEntries (string path, string pattern, FileAttributes mask, FileAttributes attrs)
  297. {
  298. SearchPattern search;
  299. MonoIOStat stat;
  300. IntPtr find;
  301. if (path.IndexOfAny (Path.InvalidPathChars) != -1) {
  302. throw new ArgumentException ("Path contains invalid characters.");
  303. }
  304. if (!Directory.Exists (path)) {
  305. throw new DirectoryNotFoundException ("Directory '" + path + "' not found.");
  306. }
  307. search = new SearchPattern (pattern);
  308. MonoIOError error;
  309. find = MonoIO.FindFirstFile (Path.Combine (path , "*"), out stat, out error);
  310. if (find == MonoIO.InvalidHandle) {
  311. switch (error) {
  312. case MonoIOError.ERROR_FILE_NOT_FOUND:
  313. case MonoIOError.ERROR_PATH_NOT_FOUND:
  314. string message = String.Format ("Could not find a part of the path \"{0}\"", path);
  315. throw new DirectoryNotFoundException (message);
  316. case MonoIOError.ERROR_NO_MORE_FILES:
  317. return new string [0];
  318. default:
  319. throw MonoIO.GetException (path,
  320. error);
  321. }
  322. }
  323. ArrayList entries = new ArrayList ();
  324. while (true) {
  325. // Ignore entries of "." and ".." -
  326. // the documentation doesn't mention
  327. // it (surprise!) but empirical
  328. // testing indicates .net never
  329. // returns "." or ".." in a
  330. // GetDirectories() list.
  331. if ((stat.Attributes & mask) == attrs &&
  332. search.IsMatch (stat.Name) &&
  333. stat.Name != "." &&
  334. stat.Name != "..")
  335. entries.Add (Path.Combine (path, stat.Name));
  336. if (!MonoIO.FindNextFile (find, out stat,
  337. out error))
  338. break;
  339. }
  340. MonoIO.FindClose (find, out error);
  341. return (string []) entries.ToArray (typeof (string));
  342. }
  343. }
  344. }