2 // System.IO.DirectoryInfo.cs
5 // Miguel de Icaza, miguel@ximian.com
6 // Jim Richardson, develop@wtfo-guru.com
7 // Dan Lewis, dihlewis@yahoo.co.uk
8 // Sebastien Pouliot <sebastien@ximian.com>
10 // Copyright (C) 2002 Ximian, Inc.
11 // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
12 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
35 using System.Runtime.InteropServices;
38 using System.Security.AccessControl;
47 public sealed class DirectoryInfo : FileSystemInfo {
49 private string current;
50 private string parent;
52 public DirectoryInfo (string path)
56 FullPath = Path.GetFullPath (path);
59 int len = FullPath.Length - 1;
60 if ((len > 1) && (FullPath [len] == Path.DirectorySeparatorChar))
62 int last = FullPath.LastIndexOf (Path.DirectorySeparatorChar, len);
63 if ((last == -1) || ((last == 0) && (len == 0))) {
67 current = FullPath.Substring (last + 1, len - last);
68 if (last == 0 && !Environment.IsRunningOnWindows)
69 parent = Path.DirectorySeparatorStr;
71 parent = FullPath.Substring (0, last);
72 // adjust for drives, i.e. a special case for windows
73 if (Environment.IsRunningOnWindows) {
74 if ((parent.Length == 2) && (parent [1] == ':') && Char.IsLetter (parent [0]))
75 parent += Path.DirectorySeparatorChar;
82 public override bool Exists {
86 if (stat.Attributes == MonoIO.InvalidFileAttributes)
89 if ((stat.Attributes & FileAttributes.Directory) == 0)
96 public override string Name {
97 get { return current; }
100 public DirectoryInfo Parent {
102 if ((parent == null) || (parent.Length == 0))
104 return new DirectoryInfo (parent);
108 public DirectoryInfo Root {
110 string root = Path.GetPathRoot (FullPath);
114 return new DirectoryInfo (root);
118 // creational methods
120 public void Create () {
121 Directory.CreateDirectory (FullPath);
124 public DirectoryInfo CreateSubdirectory (string name) {
127 if (Path.IsPathRooted (name))
128 throw new ArgumentException ();
130 if (Environment.IsRunningOnWindows)
131 if (name.IndexOf (':') != -1)
132 throw new NotSupportedException ("The given path's format is not supported.");
134 string path = Path.Combine (FullPath, name);
136 string subdirectoryPath = Path.GetFullPath (path);
138 if (!subdirectoryPath.StartsWith (FullPath))
139 throw new ArgumentException (String.Format ("The directory specified, '{0}', is not a subdirectory of '{1}'.", name, FullPath));
141 Directory.CreateDirectory (path);
143 return new DirectoryInfo (path);
146 // directory listing methods
148 public FileInfo [] GetFiles () {
149 return GetFiles ("*");
152 public FileInfo [] GetFiles (string pattern)
154 string [] names = Directory.GetFiles (FullPath, pattern);
156 FileInfo[] infos = new FileInfo [names.Length];
158 foreach (string name in names)
159 infos [i++] = new FileInfo (name);
164 public DirectoryInfo [] GetDirectories () {
165 return GetDirectories ("*");
168 public DirectoryInfo [] GetDirectories (string pattern)
170 string [] names = Directory.GetDirectories (FullPath, pattern);
172 DirectoryInfo[] infos = new DirectoryInfo [names.Length];
174 foreach (string name in names)
175 infos [i++] = new DirectoryInfo (name);
180 public FileSystemInfo [] GetFileSystemInfos () {
181 return GetFileSystemInfos ("*");
184 public FileSystemInfo [] GetFileSystemInfos (string pattern)
186 string[] dirs = Directory.GetDirectories (FullPath, pattern);
187 string[] files = Directory.GetFiles (FullPath, pattern);
189 FileSystemInfo[] infos = new FileSystemInfo [dirs.Length + files.Length];
191 foreach (string dir in dirs)
192 infos [i++] = new DirectoryInfo (dir);
193 foreach (string file in files)
194 infos [i++] = new FileInfo (file);
199 // directory management methods
201 public override void Delete () {
205 public void Delete (bool recurse) {
206 Directory.Delete (FullPath, recurse);
209 public void MoveTo (string dest) {
210 Directory.Move (FullPath, Path.GetFullPath (dest));
211 this.FullPath = Path.GetFullPath (dest);
214 public override string ToString () {
218 // additional search methods
220 public DirectoryInfo[] GetDirectories (string pattern, SearchOption searchOption)
222 switch (searchOption) {
223 case SearchOption.TopDirectoryOnly:
224 return GetDirectories (pattern);
225 case SearchOption.AllDirectories:
226 Queue workq = new Queue(GetDirectories(pattern));
227 Queue doneq = new Queue();
228 while (workq.Count > 0)
230 DirectoryInfo cinfo = (DirectoryInfo) workq.Dequeue();
231 DirectoryInfo[] cinfoDirs = cinfo.GetDirectories(pattern);
232 foreach (DirectoryInfo i in cinfoDirs) workq.Enqueue(i);
233 doneq.Enqueue(cinfo);
236 DirectoryInfo[] infos = new DirectoryInfo[doneq.Count];
237 doneq.CopyTo(infos, 0);
240 string msg = Locale.GetText ("Invalid enum value '{0}' for '{1}'.", searchOption, "SearchOption");
241 throw new ArgumentOutOfRangeException ("searchOption", msg);
245 internal int GetFilesSubdirs (ArrayList l, string pattern)
248 FileInfo [] thisdir = null;
251 thisdir = GetFiles (pattern);
252 } catch (System.UnauthorizedAccessException){
256 count = thisdir.Length;
259 foreach (DirectoryInfo subdir in GetDirectories ()){
260 count += subdir.GetFilesSubdirs (l, pattern);
265 public FileInfo[] GetFiles (string pattern, SearchOption searchOption)
267 switch (searchOption) {
268 case SearchOption.TopDirectoryOnly:
269 return GetFiles (pattern);
270 case SearchOption.AllDirectories: {
271 ArrayList groups = new ArrayList ();
272 int count = GetFilesSubdirs (groups, pattern);
275 FileInfo [] all = new FileInfo [count];
276 foreach (FileInfo [] p in groups){
277 p.CopyTo (all, current);
283 string msg = Locale.GetText ("Invalid enum value '{0}' for '{1}'.", searchOption, "SearchOption");
284 throw new ArgumentOutOfRangeException ("searchOption", msg);
288 // access control methods
290 [MonoTODO ("DirectorySecurity isn't implemented")]
291 public void Create (DirectorySecurity directorySecurity)
293 if (directorySecurity != null)
294 throw new UnauthorizedAccessException ();
298 [MonoTODO ("Mono provides no support for DirectorySecurity")]
299 public DirectoryInfo CreateSubdirectory (string name, DirectorySecurity directorySecurity)
301 if (directorySecurity != null)
302 throw new UnauthorizedAccessException ();
303 return CreateSubdirectory (name);
306 [MonoTODO ("Mono provides no support for this")]
307 public DirectorySecurity GetAccessControl ()
309 throw new UnauthorizedAccessException ();
312 [MonoTODO ("Mono provides no support for this")]
313 public DirectorySecurity GetAccessControl (AccessControlSections includeSections)
315 throw new UnauthorizedAccessException ();
318 [MonoTODO ("Mono provides no support for this")]
319 public void SetAccessControl (DirectorySecurity directorySecurity)
321 if (directorySecurity != null)
322 throw new ArgumentNullException ("directorySecurity");
323 throw new UnauthorizedAccessException ();