Directory.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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. // Ville Palo ([email protected])
  10. //
  11. // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
  12. // Copyright (C) 2002 Ximian, Inc.
  13. //
  14. // Created: Monday, August 13, 2001
  15. //
  16. //------------------------------------------------------------------------------
  17. using System;
  18. using System.Security.Permissions;
  19. using System.Collections;
  20. using System.Text;
  21. namespace System.IO
  22. {
  23. public sealed class Directory : Object
  24. {
  25. private Directory () {}
  26. public static DirectoryInfo CreateDirectory (string path)
  27. {
  28. if (path == null)
  29. throw new ArgumentNullException ("path");
  30. if (path == "")
  31. throw new ArgumentException ("Path is empty");
  32. if (path.IndexOfAny (Path.InvalidPathChars) != -1)
  33. throw new ArgumentException ("Path contains invalid chars");
  34. if (path.Trim ().Length == 0)
  35. throw new ArgumentException ("Only blank characters in path");
  36. // LAMESPEC: with .net 1.0 version this throw NotSupportedException and msdn says so too
  37. // byt v1.1 throws ArgumentException.
  38. if (path == ":")
  39. throw new ArgumentException ("Only ':' In path");
  40. return CreateDirectoriesInternal (path);
  41. }
  42. static DirectoryInfo CreateDirectoriesInternal (string path)
  43. {
  44. DirectoryInfo info = new DirectoryInfo (path);
  45. if (info.Parent != null && !info.Parent.Exists)
  46. info.Parent.Create ();
  47. MonoIOError error;
  48. if (!MonoIO.CreateDirectory (path, out error)) {
  49. if (error != MonoIOError.ERROR_ALREADY_EXISTS)
  50. throw MonoIO.GetException (error);
  51. }
  52. return info;
  53. }
  54. public static void Delete (string path)
  55. {
  56. if (path == null) {
  57. throw new ArgumentNullException ("path");
  58. }
  59. if (path == "") {
  60. throw new ArgumentException ("Path is empty");
  61. }
  62. if (path.IndexOfAny (Path.InvalidPathChars) != -1) {
  63. throw new ArgumentException ("Path contains invalid chars");
  64. }
  65. if (path.Trim().Length == 0)
  66. throw new ArgumentException ("Only blank characters in path");
  67. if (path == ":")
  68. throw new NotSupportedException ("Only ':' In path");
  69. MonoIOError error;
  70. if (!MonoIO.RemoveDirectory (path, out error)) {
  71. /*
  72. * FIXME:
  73. * In io-layer/io.c rmdir returns error_file_not_found if directory does not exists.
  74. * So maybe this could be handled somewhere else?
  75. */
  76. if (error == MonoIOError.ERROR_FILE_NOT_FOUND)
  77. throw new DirectoryNotFoundException ("Directory '" + path + "' doesnt exists.");
  78. else
  79. throw MonoIO.GetException (error);
  80. }
  81. }
  82. static void RecursiveDelete (string path)
  83. {
  84. foreach (string dir in GetDirectories (path))
  85. RecursiveDelete (dir);
  86. foreach (string file in GetFiles (path))
  87. File.Delete (file);
  88. Directory.Delete (path);
  89. }
  90. public static void Delete (string path, bool recurse)
  91. {
  92. CheckPathExceptions (path);
  93. if (recurse == false){
  94. Delete (path);
  95. return;
  96. }
  97. RecursiveDelete (path);
  98. }
  99. public static bool Exists (string path)
  100. {
  101. if (path == null)
  102. return false;
  103. MonoIOError error;
  104. return MonoIO.ExistsDirectory (path, out error);
  105. }
  106. public static DateTime GetLastAccessTime (string path)
  107. {
  108. return File.GetLastAccessTime (path);
  109. }
  110. public static DateTime GetLastAccessTimeUtc (string path)
  111. {
  112. return GetLastAccessTime (path).ToUniversalTime ();
  113. }
  114. public static DateTime GetLastWriteTime (string path)
  115. {
  116. return File.GetLastWriteTime (path);
  117. }
  118. public static DateTime GetLastWriteTimeUtc (string path)
  119. {
  120. return GetLastWriteTime (path).ToUniversalTime ();
  121. }
  122. public static DateTime GetCreationTime (string path)
  123. {
  124. return File.GetCreationTime (path);
  125. }
  126. public static DateTime GetCreationTimeUtc (string path)
  127. {
  128. return GetCreationTime (path).ToUniversalTime ();
  129. }
  130. public static string GetCurrentDirectory ()
  131. {
  132. /*
  133. // Implementation complete 08/25/2001 14:24 except for
  134. // LAMESPEC: documentation specifies invalid exceptions (i think)
  135. // also shouldn't need Write to getcurrrent should we?
  136. string str = Environment.CurrentDirectory;
  137. CheckPermission.Demand (FileIOPermissionAccess.Read & FileIOPermissionAccess.Write, str);
  138. */
  139. return Environment.CurrentDirectory;
  140. }
  141. public static string [] GetDirectories (string path)
  142. {
  143. return GetDirectories (path, "*");
  144. }
  145. public static string [] GetDirectories (string path, string pattern)
  146. {
  147. return GetFileSystemEntries (path, pattern, FileAttributes.Directory, FileAttributes.Directory);
  148. }
  149. public static string GetDirectoryRoot (string path)
  150. {
  151. return new String(Path.DirectorySeparatorChar,1);
  152. }
  153. public static string [] GetFiles (string path)
  154. {
  155. return GetFiles (path, "*");
  156. }
  157. public static string [] GetFiles (string path, string pattern)
  158. {
  159. return GetFileSystemEntries (path, pattern, FileAttributes.Directory, 0);
  160. }
  161. public static string [] GetFileSystemEntries (string path)
  162. {
  163. return GetFileSystemEntries (path, "*");
  164. }
  165. public static string [] GetFileSystemEntries (string path, string pattern)
  166. {
  167. return GetFileSystemEntries (path, pattern, 0, 0);
  168. }
  169. [MonoTODO("Implement on windows, for real")]
  170. public static string[] GetLogicalDrives ()
  171. {
  172. //FIXME: Hardcoded Paths
  173. if (Environment.OSVersion.Platform == PlatformID.Unix)
  174. return new string[] { "/" };
  175. else
  176. return new string [] { "A:\\", "C:\\" };
  177. }
  178. public static DirectoryInfo GetParent (string path)
  179. {
  180. if (path == null)
  181. throw new ArgumentNullException ();
  182. if (path.IndexOfAny (Path.InvalidPathChars) != -1)
  183. throw new ArgumentException ("Path contains invalid characters");
  184. if (path == "")
  185. throw new ArgumentException ("The Path do not have a valid format");
  186. return new DirectoryInfo (Path.GetDirectoryName (path));
  187. }
  188. public static void Move (string src, string dest)
  189. {
  190. if (src == null)
  191. throw new ArgumentNullException ("src");
  192. if (dest == null)
  193. throw new ArgumentNullException ("dest");
  194. if (src.Trim () == "" || src.IndexOfAny (Path.InvalidPathChars) != -1)
  195. throw new ArgumentException ("Invalid source directory name: " + src, "src");
  196. if (dest.Trim () == "" || dest.IndexOfAny (Path.InvalidPathChars) != -1)
  197. throw new ArgumentException ("Invalid target directory name: " + dest, "dest");
  198. if (src == dest)
  199. throw new IOException ("Source directory cannot be same as a target directory.");
  200. if (Exists (dest))
  201. throw new IOException (dest + " already exists.");
  202. if (!Exists (src))
  203. throw new DirectoryNotFoundException (src + " does not exist");
  204. MonoIOError error;
  205. if (!MonoIO.MoveFile (src, dest, out error))
  206. throw MonoIO.GetException (error);
  207. }
  208. public static void SetCreationTime (string path, DateTime creation_time)
  209. {
  210. File.SetCreationTime (path, creation_time);
  211. }
  212. public static void SetCreationTimeUtc (string path, DateTime creation_time)
  213. {
  214. SetCreationTime (path, creation_time.ToLocalTime ());
  215. }
  216. public static void SetCurrentDirectory (string path)
  217. {
  218. /*
  219. // Implementation complete 08/25/2001 14:24 except for
  220. // LAMESPEC: documentation specifies invalid exceptions IOException (i think)
  221. CheckArgument.Path (path, true);
  222. CheckPermission.Demand (FileIOPermissionAccess.Read & FileIOPermissionAccess.Write, path);
  223. */
  224. if (!Exists (path))
  225. {
  226. throw new DirectoryNotFoundException ("Directory \"" + path + "\" not found.");
  227. }
  228. Environment.CurrentDirectory = path;
  229. }
  230. public static void SetLastAccessTime (string path, DateTime last_access_time)
  231. {
  232. File.SetLastAccessTime (path, last_access_time);
  233. }
  234. public static void SetLastAccessTimeUtc (string path, DateTime last_access_time)
  235. {
  236. SetLastAccessTime (path, last_access_time.ToLocalTime ());
  237. }
  238. public static void SetLastWriteTime (string path, DateTime last_write_time)
  239. {
  240. File.SetLastWriteTime (path, last_write_time);
  241. }
  242. public static void SetLastWriteTimeUtc (string path, DateTime last_write_time)
  243. {
  244. SetLastWriteTime (path, last_write_time.ToLocalTime ());
  245. }
  246. // private
  247. private static void CheckPathExceptions (string path)
  248. {
  249. if (path == null)
  250. throw new System.ArgumentNullException("Path is Null");
  251. if (path == "")
  252. throw new System.ArgumentException("Path is Empty");
  253. if (path.Trim().Length == 0)
  254. throw new ArgumentException ("Only blank characters in path");
  255. if (path.IndexOfAny (Path.InvalidPathChars) != -1)
  256. throw new ArgumentException ("Path contains invalid chars");
  257. }
  258. private static string [] GetFileSystemEntries (string path, string pattern, FileAttributes mask, FileAttributes attrs)
  259. {
  260. SearchPattern search;
  261. MonoIOStat stat;
  262. IntPtr find;
  263. if (path == null || pattern == null)
  264. throw new ArgumentNullException ();
  265. if (path == "")
  266. throw new ArgumentException ("The Path do not have a valid format");
  267. if (path.IndexOfAny (Path.InvalidPathChars) != -1)
  268. throw new ArgumentException ("Path contains invalid characters");
  269. if (!Directory.Exists (path)) {
  270. throw new DirectoryNotFoundException ("Directory '" + path + "' not found.");
  271. }
  272. search = new SearchPattern (pattern);
  273. MonoIOError error;
  274. find = MonoIO.FindFirstFile (Path.Combine (path , "*"), out stat, out error);
  275. if (find == MonoIO.InvalidHandle) {
  276. switch (error) {
  277. case MonoIOError.ERROR_FILE_NOT_FOUND:
  278. case MonoIOError.ERROR_PATH_NOT_FOUND:
  279. string message = String.Format ("Could not find a part of the path \"{0}\"", path);
  280. throw new DirectoryNotFoundException (message);
  281. case MonoIOError.ERROR_NO_MORE_FILES:
  282. return new string [0];
  283. default:
  284. throw MonoIO.GetException (path,
  285. error);
  286. }
  287. }
  288. ArrayList entries = new ArrayList ();
  289. while (true) {
  290. // Ignore entries of "." and ".." -
  291. // the documentation doesn't mention
  292. // it (surprise!) but empirical
  293. // testing indicates .net never
  294. // returns "." or ".." in a
  295. // GetDirectories() list.
  296. if ((stat.Attributes & mask) == attrs &&
  297. search.IsMatch (stat.Name) &&
  298. stat.Name != "." &&
  299. stat.Name != "..")
  300. entries.Add (Path.Combine (path, stat.Name));
  301. if (!MonoIO.FindNextFile (find, out stat,
  302. out error))
  303. break;
  304. }
  305. MonoIO.FindClose (find, out error);
  306. return (string []) entries.ToArray (typeof (string));
  307. }
  308. }
  309. }