| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536 |
- //
- // System.IO.Directory.cs
- //
- // Authors:
- // Jim Richardson ([email protected])
- // Miguel de Icaza ([email protected])
- // Dan Lewis ([email protected])
- // Eduardo Garcia ([email protected])
- // Ville Palo ([email protected])
- //
- // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
- // Copyright (C) 2002 Ximian, Inc.
- //
- // Created: Monday, August 13, 2001
- //
- //------------------------------------------------------------------------------
- //
- // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System.Collections;
- using System.Security;
- using System.Security.Permissions;
- using System.Text;
- using System.Runtime.InteropServices;
- #if !NET_2_1 || MONOTOUCH
- using System.Security.AccessControl;
- #endif
- namespace System.IO
- {
- [ComVisible (true)]
- public static class Directory
- {
- public static DirectoryInfo CreateDirectory (string path)
- {
- if (path == null)
- throw new ArgumentNullException ("path");
-
- if (path.Length == 0)
- throw new ArgumentException ("Path is empty");
-
- if (path.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException ("Path contains invalid chars");
- if (path.Trim ().Length == 0)
- throw new ArgumentException ("Only blank characters in path");
- if (File.Exists(path))
- throw new IOException ("Cannot create " + path + " because a file with the same name already exists.");
-
- // LAMESPEC: with .net 1.0 version this throw NotSupportedException and msdn says so too
- // but v1.1 throws ArgumentException.
- if (path == ":")
- throw new ArgumentException ("Only ':' In path");
-
- return CreateDirectoriesInternal (path);
- }
- #if !NET_2_1 || MONOTOUCH
- [MonoLimitation ("DirectorySecurity not implemented")]
- public static DirectoryInfo CreateDirectory (string path, DirectorySecurity directorySecurity)
- {
- return(CreateDirectory (path));
- }
- #endif
- static DirectoryInfo CreateDirectoriesInternal (string path)
- {
- #if !NET_2_1 || MONOTOUCH
- if (SecurityManager.SecurityEnabled) {
- new FileIOPermission (FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, path).Demand ();
- }
- #endif
- DirectoryInfo info = new DirectoryInfo (path, true);
- if (info.Parent != null && !info.Parent.Exists)
- info.Parent.Create ();
- MonoIOError error;
- if (!MonoIO.CreateDirectory (path, out error)) {
- // LAMESPEC: 1.1 and 1.2alpha allow CreateDirectory on a file path.
- // So CreateDirectory ("/tmp/somefile") will succeed if 'somefile' is
- // not a directory. However, 1.0 will throw an exception.
- // We behave like 1.0 here (emulating 1.1-like behavior is just a matter
- // of comparing error to ERROR_FILE_EXISTS, but it's lame to do:
- // DirectoryInfo di = Directory.CreateDirectory (something);
- // and having di.Exists return false afterwards.
- // I hope we don't break anyone's code, as they should be catching
- // the exception anyway.
- if (error != MonoIOError.ERROR_ALREADY_EXISTS &&
- error != MonoIOError.ERROR_FILE_EXISTS)
- throw MonoIO.GetException (path, error);
- }
- return info;
- }
-
- public static void Delete (string path)
- {
- if (path == null)
- throw new ArgumentNullException ("path");
-
- if (path.Length == 0)
- throw new ArgumentException ("Path is empty");
-
- if (path.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException ("Path contains invalid chars");
- if (path.Trim().Length == 0)
- throw new ArgumentException ("Only blank characters in path");
- if (path == ":")
- throw new NotSupportedException ("Only ':' In path");
- MonoIOError error;
- bool success;
-
- if (MonoIO.ExistsSymlink (path, out error)) {
- /* RemoveDirectory maps to rmdir()
- * which fails on symlinks (ENOTDIR)
- */
- success = MonoIO.DeleteFile (path, out error);
- } else {
- success = MonoIO.RemoveDirectory (path, out error);
- }
-
- if (!success) {
- /*
- * FIXME:
- * In io-layer/io.c rmdir returns error_file_not_found if directory does not exists.
- * So maybe this could be handled somewhere else?
- */
- if (error == MonoIOError.ERROR_FILE_NOT_FOUND) {
- if (File.Exists (path))
- throw new IOException ("Directory does not exist, but a file of the same name exist.");
- else
- throw new DirectoryNotFoundException ("Directory does not exist.");
- } else
- throw MonoIO.GetException (path, error);
- }
- }
- static void RecursiveDelete (string path)
- {
- MonoIOError error;
-
- foreach (string dir in GetDirectories (path)) {
- if (MonoIO.ExistsSymlink (dir, out error)) {
- MonoIO.DeleteFile (dir, out error);
- } else {
- RecursiveDelete (dir);
- }
- }
- foreach (string file in GetFiles (path))
- File.Delete (file);
- Directory.Delete (path);
- }
-
- public static void Delete (string path, bool recursive)
- {
- CheckPathExceptions (path);
-
- if (recursive)
- RecursiveDelete (path);
- else
- Delete (path);
- }
- public static bool Exists (string path)
- {
- if (path == null)
- return false;
-
- MonoIOError error;
- bool exists;
-
- exists = MonoIO.ExistsDirectory (path, out error);
- if (error != MonoIOError.ERROR_SUCCESS &&
- error != MonoIOError.ERROR_PATH_NOT_FOUND &&
- error != MonoIOError.ERROR_INVALID_HANDLE &&
- error != MonoIOError.ERROR_ACCESS_DENIED) {
- // INVALID_HANDLE might happen if the file is moved
- // while testing for the existence, a kernel issue
- // according to Larry Ewing.
-
- throw MonoIO.GetException (path, error);
- }
- return(exists);
- }
- public static DateTime GetLastAccessTime (string path)
- {
- return File.GetLastAccessTime (path);
- }
- public static DateTime GetLastAccessTimeUtc (string path)
- {
- return GetLastAccessTime (path).ToUniversalTime ();
- }
- public static DateTime GetLastWriteTime (string path)
- {
- return File.GetLastWriteTime (path);
- }
-
- public static DateTime GetLastWriteTimeUtc (string path)
- {
- return GetLastWriteTime (path).ToUniversalTime ();
- }
- public static DateTime GetCreationTime (string path)
- {
- return File.GetCreationTime (path);
- }
- public static DateTime GetCreationTimeUtc (string path)
- {
- return GetCreationTime (path).ToUniversalTime ();
- }
- public static string GetCurrentDirectory ()
- {
- MonoIOError error;
-
- string result = MonoIO.GetCurrentDirectory (out error);
- if (error != MonoIOError.ERROR_SUCCESS)
- throw MonoIO.GetException (error);
- #if !NET_2_1 || MONOTOUCH
- if ((result != null) && (result.Length > 0) && SecurityManager.SecurityEnabled) {
- new FileIOPermission (FileIOPermissionAccess.PathDiscovery, result).Demand ();
- }
- #endif
- return result;
- }
-
- public static string [] GetDirectories (string path)
- {
- return GetDirectories (path, "*");
- }
-
- public static string [] GetDirectories (string path, string searchPattern)
- {
- return GetFileSystemEntries (path, searchPattern, FileAttributes.Directory, FileAttributes.Directory);
- }
-
- #if !NET_2_1 || MONOTOUCH
- public static string [] GetDirectories (string path, string searchPattern, SearchOption searchOption)
- {
- if (searchOption == SearchOption.TopDirectoryOnly)
- return GetDirectories (path, searchPattern);
- ArrayList all = new ArrayList ();
- GetDirectoriesRecurse (path, searchPattern, all);
- return (string []) all.ToArray (typeof (string));
- }
-
- static void GetDirectoriesRecurse (string path, string searchPattern, ArrayList all)
- {
- all.AddRange (GetDirectories (path, searchPattern));
- foreach (string dir in GetDirectories (path))
- GetDirectoriesRecurse (dir, searchPattern, all);
- }
- #endif
- public static string GetDirectoryRoot (string path)
- {
- return new String(Path.DirectorySeparatorChar,1);
- }
-
- public static string [] GetFiles (string path)
- {
- return GetFiles (path, "*");
- }
-
- public static string [] GetFiles (string path, string searchPattern)
- {
- return GetFileSystemEntries (path, searchPattern, FileAttributes.Directory, 0);
- }
- #if !NET_2_1 || MONOTOUCH
- public static string[] GetFiles (string path, string searchPattern, SearchOption searchOption)
- {
- if (searchOption == SearchOption.TopDirectoryOnly)
- return GetFiles (path, searchPattern);
- ArrayList all = new ArrayList ();
- GetFilesRecurse (path, searchPattern, all);
- return (string []) all.ToArray (typeof (string));
- }
-
- static void GetFilesRecurse (string path, string searchPattern, ArrayList all)
- {
- all.AddRange (GetFiles (path, searchPattern));
- foreach (string dir in GetDirectories (path))
- GetFilesRecurse (dir, searchPattern, all);
- }
- #endif
- public static string [] GetFileSystemEntries (string path)
- {
- return GetFileSystemEntries (path, "*");
- }
- public static string [] GetFileSystemEntries (string path, string searchPattern)
- {
- return GetFileSystemEntries (path, searchPattern, 0, 0);
- }
-
- public static string[] GetLogicalDrives ()
- {
- return Environment.GetLogicalDrives ();
- }
- static bool IsRootDirectory (string path)
- {
- // Unix
- if (Path.DirectorySeparatorChar == '/' && path == "/")
- return true;
- // Windows
- if (Path.DirectorySeparatorChar == '\\')
- if (path.Length == 3 && path.EndsWith (":\\"))
- return true;
- return false;
- }
- public static DirectoryInfo GetParent (string path)
- {
- if (path == null)
- throw new ArgumentNullException ("path");
- if (path.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException ("Path contains invalid characters");
- if (path.Length == 0)
- throw new ArgumentException ("The Path do not have a valid format");
- // return null if the path is the root directory
- if (IsRootDirectory (path))
- return null;
- string parent_name = Path.GetDirectoryName (path);
- if (parent_name.Length == 0)
- parent_name = GetCurrentDirectory();
- return new DirectoryInfo (parent_name);
- }
- public static void Move (string sourceDirName, string destDirName)
- {
- if (sourceDirName == null)
- throw new ArgumentNullException ("sourceDirName");
- if (destDirName == null)
- throw new ArgumentNullException ("destDirName");
- if (sourceDirName.Trim ().Length == 0 || sourceDirName.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException ("Invalid source directory name: " + sourceDirName, "sourceDirName");
- if (destDirName.Trim ().Length == 0 || destDirName.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException ("Invalid target directory name: " + destDirName, "destDirName");
- if (sourceDirName == destDirName)
- throw new IOException ("Source and destination path must be different.");
- if (Exists (destDirName))
- throw new IOException (destDirName + " already exists.");
- if (!Exists (sourceDirName) && !File.Exists (sourceDirName))
- throw new DirectoryNotFoundException (sourceDirName + " does not exist");
- MonoIOError error;
- if (!MonoIO.MoveFile (sourceDirName, destDirName, out error))
- throw MonoIO.GetException (error);
- }
- #if !NET_2_1 || MONOTOUCH
- public static void SetAccessControl (string path, DirectorySecurity directorySecurity)
- {
- throw new NotImplementedException ();
- }
- #endif
- public static void SetCreationTime (string path, DateTime creationTime)
- {
- File.SetCreationTime (path, creationTime);
- }
- public static void SetCreationTimeUtc (string path, DateTime creationTimeUtc)
- {
- SetCreationTime (path, creationTimeUtc.ToLocalTime ());
- }
- [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
- public static void SetCurrentDirectory (string path)
- {
- if (path == null)
- throw new ArgumentNullException ("path");
- if (path.Trim ().Length == 0)
- throw new ArgumentException ("path string must not be an empty string or whitespace string");
- MonoIOError error;
-
- if (!Exists (path))
- throw new DirectoryNotFoundException ("Directory \"" +
- path + "\" not found.");
- MonoIO.SetCurrentDirectory (path, out error);
- if (error != MonoIOError.ERROR_SUCCESS)
- throw MonoIO.GetException (path, error);
- }
- public static void SetLastAccessTime (string path, DateTime lastAccessTime)
- {
- File.SetLastAccessTime (path, lastAccessTime);
- }
- public static void SetLastAccessTimeUtc (string path, DateTime lastAccessTimeUtc)
- {
- SetLastAccessTime (path, lastAccessTimeUtc.ToLocalTime ());
- }
- public static void SetLastWriteTime (string path, DateTime lastWriteTime)
- {
- File.SetLastWriteTime (path, lastWriteTime);
- }
- public static void SetLastWriteTimeUtc (string path, DateTime lastWriteTimeUtc)
- {
- SetLastWriteTime (path, lastWriteTimeUtc.ToLocalTime ());
- }
- // private
-
- private static void CheckPathExceptions (string path)
- {
- if (path == null)
- throw new System.ArgumentNullException("path");
- if (path.Length == 0)
- throw new System.ArgumentException("Path is Empty");
- if (path.Trim().Length == 0)
- throw new ArgumentException ("Only blank characters in path");
- if (path.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException ("Path contains invalid chars");
- }
- private static string [] GetFileSystemEntries (string path, string searchPattern, FileAttributes mask, FileAttributes attrs)
- {
- if (path == null || searchPattern == null)
- throw new ArgumentNullException ();
- if (searchPattern.Length == 0)
- return new string [] {};
-
- if (path.Trim ().Length == 0)
- throw new ArgumentException ("The Path does not have a valid format");
- string wild = Path.Combine (path, searchPattern);
- string wildpath = Path.GetDirectoryName (wild);
- if (wildpath.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException ("Path contains invalid characters");
- if (wildpath.IndexOfAny (Path.InvalidPathChars) != -1) {
- if (path.IndexOfAny (SearchPattern.InvalidChars) == -1)
- throw new ArgumentException ("Path contains invalid characters", "path");
- throw new ArgumentException ("Pattern contains invalid characters", "pattern");
- }
- MonoIOError error;
- if (!MonoIO.ExistsDirectory (wildpath, out error)) {
- if (error == MonoIOError.ERROR_SUCCESS) {
- MonoIOError file_error;
- if (MonoIO.ExistsFile (wildpath, out file_error)) {
- return new string [] { wildpath };
- }
- }
- if (error != MonoIOError.ERROR_PATH_NOT_FOUND)
- throw MonoIO.GetException (wildpath, error);
- if (wildpath.IndexOfAny (SearchPattern.WildcardChars) == -1)
- throw new DirectoryNotFoundException ("Directory '" + wildpath + "' not found.");
- if (path.IndexOfAny (SearchPattern.WildcardChars) == -1)
- throw new ArgumentException ("Pattern is invalid", "searchPattern");
- throw new ArgumentException ("Path is invalid", "path");
- }
- string path_with_pattern = Path.Combine (wildpath, searchPattern);
- string [] result = MonoIO.GetFileSystemEntries (path, path_with_pattern, (int) attrs, (int) mask, out error);
- if (error != 0)
- throw MonoIO.GetException (wildpath, error);
-
- return result;
- }
- #if !NET_2_1 || MONOTOUCH
- [MonoNotSupported ("DirectorySecurity isn't implemented")]
- public static DirectorySecurity GetAccessControl (string path, AccessControlSections includeSections)
- {
- throw new PlatformNotSupportedException ();
- }
- [MonoNotSupported ("DirectorySecurity isn't implemented")]
- public static DirectorySecurity GetAccessControl (string path)
- {
- throw new PlatformNotSupportedException ();
- }
- #endif
- }
- }
|