2 // System.IO.Directory.cs
5 // Jim Richardson (develop@wtfo-guru.com)
6 // Miguel de Icaza (miguel@ximian.com)
7 // Dan Lewis (dihlewis@yahoo.co.uk)
8 // Eduardo Garcia (kiwnix@yahoo.es)
9 // Ville Palo (vi64pa@kolumbus.fi)
11 // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
12 // Copyright (C) 2002 Ximian, Inc.
14 // Created: Monday, August 13, 2001
16 //------------------------------------------------------------------------------
19 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
21 // Permission is hereby granted, free of charge, to any person obtaining
22 // a copy of this software and associated documentation files (the
23 // "Software"), to deal in the Software without restriction, including
24 // without limitation the rights to use, copy, modify, merge, publish,
25 // distribute, sublicense, and/or sell copies of the Software, and to
26 // permit persons to whom the Software is furnished to do so, subject to
27 // the following conditions:
29 // The above copyright notice and this permission notice shall be
30 // included in all copies or substantial portions of the Software.
32 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
35 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
36 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
37 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
38 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 using System
.Security
.Permissions
;
43 using System
.Collections
;
58 private Directory () {}
61 public static DirectoryInfo
CreateDirectory (string path
)
64 throw new ArgumentNullException ("path");
67 throw new ArgumentException ("Path is empty");
69 if (path
.IndexOfAny (Path
.InvalidPathChars
) != -1)
70 throw new ArgumentException ("Path contains invalid chars");
72 if (path
.Trim ().Length
== 0)
73 throw new ArgumentException ("Only blank characters in path");
75 // LAMESPEC: with .net 1.0 version this throw NotSupportedException and msdn says so too
76 // but v1.1 throws ArgumentException.
78 throw new ArgumentException ("Only ':' In path");
80 return CreateDirectoriesInternal (path
);
83 static DirectoryInfo
CreateDirectoriesInternal (string path
)
85 DirectoryInfo info
= new DirectoryInfo (path
);
86 if (info
.Parent
!= null && !info
.Parent
.Exists
)
87 info
.Parent
.Create ();
90 if (!MonoIO
.CreateDirectory (path
, out error
)) {
91 // LAMESPEC: 1.1 and 1.2alpha allow CreateDirectory on a file path.
92 // So CreateDirectory ("/tmp/somefile") will succeed if 'somefile' is
93 // not a directory. However, 1.0 will throw an exception.
94 // We behave like 1.0 here (emulating 1.1-like behavior is just a matter
95 // of comparing error to ERROR_FILE_EXISTS, but it's lame to do:
96 // DirectoryInfo di = Directory.CreateDirectory (something);
97 // and having di.Exists return false afterwards.
98 // I hope we don't break anyone's code, as they should be catching
99 // the exception anyway.
100 if (error
!= MonoIOError
.ERROR_ALREADY_EXISTS
)
101 throw MonoIO
.GetException (path
, error
);
107 public static void Delete (string path
)
110 throw new ArgumentNullException ("path");
113 throw new ArgumentException ("Path is empty");
115 if (path
.IndexOfAny (Path
.InvalidPathChars
) != -1)
116 throw new ArgumentException ("Path contains invalid chars");
118 if (path
.Trim().Length
== 0)
119 throw new ArgumentException ("Only blank characters in path");
122 throw new NotSupportedException ("Only ':' In path");
126 if (!MonoIO
.RemoveDirectory (path
, out error
)) {
129 * In io-layer/io.c rmdir returns error_file_not_found if directory does not exists.
130 * So maybe this could be handled somewhere else?
132 if (error
== MonoIOError
.ERROR_FILE_NOT_FOUND
)
133 throw new DirectoryNotFoundException ("Directory '" + path
+ "' doesnt exists.");
135 throw MonoIO
.GetException (path
, error
);
139 static void RecursiveDelete (string path
)
141 foreach (string dir
in GetDirectories (path
))
142 RecursiveDelete (dir
);
144 foreach (string file
in GetFiles (path
))
147 Directory
.Delete (path
);
150 public static void Delete (string path
, bool recurse
)
152 CheckPathExceptions (path
);
154 if (recurse
== false){
159 RecursiveDelete (path
);
162 public static bool Exists (string path
)
170 exists
= MonoIO
.ExistsDirectory (path
, out error
);
171 if (error
!= MonoIOError
.ERROR_SUCCESS
&&
172 error
!= MonoIOError
.ERROR_PATH_NOT_FOUND
) {
173 throw MonoIO
.GetException (path
, error
);
179 public static DateTime
GetLastAccessTime (string path
)
181 return File
.GetLastAccessTime (path
);
184 public static DateTime
GetLastAccessTimeUtc (string path
)
186 return GetLastAccessTime (path
).ToUniversalTime ();
189 public static DateTime
GetLastWriteTime (string path
)
191 return File
.GetLastWriteTime (path
);
194 public static DateTime
GetLastWriteTimeUtc (string path
)
196 return GetLastWriteTime (path
).ToUniversalTime ();
199 public static DateTime
GetCreationTime (string path
)
201 return File
.GetCreationTime (path
);
204 public static DateTime
GetCreationTimeUtc (string path
)
206 return GetCreationTime (path
).ToUniversalTime ();
209 public static string GetCurrentDirectory ()
212 // Implementation complete 08/25/2001 14:24 except for
213 // LAMESPEC: documentation specifies invalid exceptions (i think)
214 // also shouldn't need Write to getcurrrent should we?
215 string str = Environment.CurrentDirectory;
216 CheckPermission.Demand (FileIOPermissionAccess.Read & FileIOPermissionAccess.Write, str);
221 string result
= MonoIO
.GetCurrentDirectory (out error
);
222 if (error
!= MonoIOError
.ERROR_SUCCESS
)
223 throw MonoIO
.GetException (error
);
228 public static string [] GetDirectories (string path
)
230 return GetDirectories (path
, "*");
233 public static string [] GetDirectories (string path
, string pattern
)
235 return GetFileSystemEntries (path
, pattern
, FileAttributes
.Directory
, FileAttributes
.Directory
);
238 public static string GetDirectoryRoot (string path
)
240 return new String(Path
.DirectorySeparatorChar
,1);
243 public static string [] GetFiles (string path
)
245 return GetFiles (path
, "*");
248 public static string [] GetFiles (string path
, string pattern
)
250 return GetFileSystemEntries (path
, pattern
, FileAttributes
.Directory
, 0);
253 public static string [] GetFileSystemEntries (string path
)
255 return GetFileSystemEntries (path
, "*");
258 public static string [] GetFileSystemEntries (string path
, string pattern
)
260 return GetFileSystemEntries (path
, pattern
, 0, 0);
263 public static string[] GetLogicalDrives ()
265 return Environment
.GetLogicalDrives ();
268 static bool IsRootDirectory (string path
)
271 if (Path
.DirectorySeparatorChar
== '/' && path
== "/")
275 if (Path
.DirectorySeparatorChar
== '\\')
276 if (path
.Length
== 3 && path
.EndsWith (":\\"))
282 public static DirectoryInfo
GetParent (string path
)
285 throw new ArgumentNullException ();
286 if (path
.IndexOfAny (Path
.InvalidPathChars
) != -1)
287 throw new ArgumentException ("Path contains invalid characters");
289 throw new ArgumentException ("The Path do not have a valid format");
291 // return null if the path is the root directory
292 if (IsRootDirectory (path
))
295 return new DirectoryInfo (Path
.GetDirectoryName (path
));
298 public static void Move (string src
, string dest
)
301 throw new ArgumentNullException ("src");
304 throw new ArgumentNullException ("dest");
306 if (src
.Trim () == "" || src
.IndexOfAny (Path
.InvalidPathChars
) != -1)
307 throw new ArgumentException ("Invalid source directory name: " + src
, "src");
309 if (dest
.Trim () == "" || dest
.IndexOfAny (Path
.InvalidPathChars
) != -1)
310 throw new ArgumentException ("Invalid target directory name: " + dest
, "dest");
313 throw new IOException ("Source directory cannot be same as a target directory.");
316 throw new IOException (dest
+ " already exists.");
319 throw new DirectoryNotFoundException (src
+ " does not exist");
322 if (!MonoIO
.MoveFile (src
, dest
, out error
))
323 throw MonoIO
.GetException (error
);
326 public static void SetCreationTime (string path
, DateTime creation_time
)
328 File
.SetCreationTime (path
, creation_time
);
331 public static void SetCreationTimeUtc (string path
, DateTime creation_time
)
333 SetCreationTime (path
, creation_time
.ToLocalTime ());
336 public static void SetCurrentDirectory (string path
)
339 // Implementation complete 08/25/2001 14:24 except for
340 // LAMESPEC: documentation specifies invalid exceptions IOException (i think)
341 CheckArgument.Path (path, true);
342 CheckPermission.Demand (FileIOPermissionAccess.Read & FileIOPermissionAccess.Write, path);
345 throw new ArgumentNullException ("path");
346 if (path
.Trim () == String
.Empty
)
347 throw new ArgumentException ("path string must not be an empty string or whitespace string");
352 throw new DirectoryNotFoundException ("Directory \"" +
353 path
+ "\" not found.");
355 MonoIO
.SetCurrentDirectory (path
, out error
);
356 if (error
!= MonoIOError
.ERROR_SUCCESS
)
357 throw MonoIO
.GetException (path
, error
);
360 public static void SetLastAccessTime (string path
, DateTime last_access_time
)
362 File
.SetLastAccessTime (path
, last_access_time
);
365 public static void SetLastAccessTimeUtc (string path
, DateTime last_access_time
)
367 SetLastAccessTime (path
, last_access_time
.ToLocalTime ());
370 public static void SetLastWriteTime (string path
, DateTime last_write_time
)
372 File
.SetLastWriteTime (path
, last_write_time
);
375 public static void SetLastWriteTimeUtc (string path
, DateTime last_write_time
)
377 SetLastWriteTime (path
, last_write_time
.ToLocalTime ());
382 private static void CheckPathExceptions (string path
)
385 throw new System
.ArgumentNullException("Path is Null");
387 throw new System
.ArgumentException("Path is Empty");
388 if (path
.Trim().Length
== 0)
389 throw new ArgumentException ("Only blank characters in path");
390 if (path
.IndexOfAny (Path
.InvalidPathChars
) != -1)
391 throw new ArgumentException ("Path contains invalid chars");
394 private static string [] GetFileSystemEntries (string path
, string pattern
, FileAttributes mask
, FileAttributes attrs
)
399 if (path
== null || pattern
== null)
400 throw new ArgumentNullException ();
402 if (pattern
== String
.Empty
)
403 return new string [] {};
405 if (path
.Trim () == "")
406 throw new ArgumentException ("The Path does not have a valid format");
408 string wild
= Path
.Combine (path
, pattern
);
409 string wildpath
= Path
.GetDirectoryName (wild
);
410 if (wildpath
.IndexOfAny (Path
.InvalidPathChars
) != -1)
411 throw new ArgumentException ("Path contains invalid characters");
413 if (wildpath
.IndexOfAny (Path
.InvalidPathChars
) != -1) {
414 if (path
.IndexOfAny (SearchPattern
.InvalidChars
) == -1)
415 throw new ArgumentException ("Path contains invalid characters", "path");
417 throw new ArgumentException ("Pattern contains invalid characters", "pattern");
421 if (!MonoIO
.ExistsDirectory (wildpath
, out error
)) {
422 if (error
!= MonoIOError
.ERROR_PATH_NOT_FOUND
)
423 throw MonoIO
.GetException (wildpath
, error
);
425 if (wildpath
.IndexOfAny (SearchPattern
.WildcardChars
) == -1)
426 throw new DirectoryNotFoundException ("Directory '" + wildpath
+ "' not found.");
428 if (path
.IndexOfAny (SearchPattern
.WildcardChars
) == -1)
429 throw new ArgumentException ("Pattern is invalid", "pattern");
431 throw new ArgumentException ("Path is invalid", "path");
434 find
= MonoIO
.FindFirstFile (wild
, out stat
, out error
);
435 if (find
== MonoIO
.InvalidHandle
) {
437 case MonoIOError
.ERROR_PATH_NOT_FOUND
:
438 string message
= String
.Format ("Could not find a part of the path \"{0}\"",
440 throw new DirectoryNotFoundException (message
);
441 case MonoIOError
.ERROR_FILE_NOT_FOUND
:
442 case MonoIOError
.ERROR_NO_MORE_FILES
:
443 return new string [0];
446 throw MonoIO
.GetException (wildpath
, error
);
450 ArrayList entries
= new ArrayList ();
453 if ((stat
.Attributes
& mask
) == attrs
)
454 entries
.Add (Path
.Combine (wildpath
, stat
.Name
));
455 } while (MonoIO
.FindNextFile (find
, out stat
, out error
));
457 MonoIO
.FindClose (find
, out error
);
459 return (string []) entries
.ToArray (typeof (string));