add System.Net.Http.Formatting to monodroid build
[mono-project.git] / mcs / class / corlib / System.IO / File.cs
blobc4ed76b34bfb513728eed443ef12e521b1e1dc03
1 //
2 // System.IO.File.cs
3 //
4 //
5 // Authors:
6 // Miguel de Icaza (miguel@ximian.com)
7 // Jim Richardson (develop@wtfo-guru.com)
8 // Dan Lewis (dihlewis@yahoo.co.uk)
9 // Ville Palo (vi64pa@kolumbus.fi)
11 // Copyright 2002 Ximian, Inc. http://www.ximian.com
12 // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
13 // Copyright (C) 2004, 2006, 2010 Novell, Inc (http://www.novell.com)
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 //
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 //
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System;
36 using System.Collections.Generic;
37 using System.Diagnostics;
38 using System.Security;
39 using System.Text;
40 using System.Runtime.InteropServices;
42 #if !NET_2_1
43 using System.Security.AccessControl;
44 #endif
46 namespace System.IO
48 [ComVisible (true)]
49 public static class File
51 public static void AppendAllText (string path, string contents)
53 using (TextWriter w = new StreamWriter (path, true)) {
54 w.Write (contents);
58 public static void AppendAllText (string path, string contents, Encoding encoding)
60 using (TextWriter w = new StreamWriter (path, true, encoding)) {
61 w.Write (contents);
65 public static StreamWriter AppendText (string path)
67 return new StreamWriter (path, true);
70 public static void Copy (string sourceFileName, string destFileName)
72 Copy (sourceFileName, destFileName, false);
75 public static void Copy (string sourceFileName, string destFileName, bool overwrite)
77 MonoIOError error;
79 if (sourceFileName == null)
80 throw new ArgumentNullException ("sourceFileName");
81 if (destFileName == null)
82 throw new ArgumentNullException ("destFileName");
83 if (sourceFileName.Length == 0)
84 throw new ArgumentException ("An empty file name is not valid.", "sourceFileName");
85 if (sourceFileName.Trim ().Length == 0 || sourceFileName.IndexOfAny (Path.InvalidPathChars) != -1)
86 throw new ArgumentException ("The file name is not valid.");
87 if (destFileName.Length == 0)
88 throw new ArgumentException ("An empty file name is not valid.", "destFileName");
89 if (destFileName.Trim ().Length == 0 || destFileName.IndexOfAny (Path.InvalidPathChars) != -1)
90 throw new ArgumentException ("The file name is not valid.");
92 SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
94 if (!MonoIO.Exists (sourceFileName, out error))
95 throw new FileNotFoundException (Locale.GetText ("{0} does not exist", sourceFileName), sourceFileName);
96 if ((GetAttributes (sourceFileName) & FileAttributes.Directory) == FileAttributes.Directory)
97 throw new ArgumentException (Locale.GetText ("{0} is a directory", sourceFileName));
99 if (MonoIO.Exists (destFileName, out error)) {
100 if ((GetAttributes (destFileName) & FileAttributes.Directory) == FileAttributes.Directory)
101 throw new ArgumentException (Locale.GetText ("{0} is a directory", destFileName));
102 if (!overwrite)
103 throw new IOException (Locale.GetText ("{0} already exists", destFileName));
106 string DirName = Path.GetDirectoryName (destFileName);
107 if (DirName != String.Empty && !Directory.Exists (DirName))
108 throw new DirectoryNotFoundException (Locale.GetText ("Destination directory not found: {0}",DirName));
110 if (!MonoIO.CopyFile (sourceFileName, destFileName, overwrite, out error)) {
111 string p = Locale.GetText ("{0}\" or \"{1}", sourceFileName, destFileName);
112 throw MonoIO.GetException (p, error);
116 public static FileStream Create (string path)
118 return Create (path, 8192);
121 public static FileStream Create (string path, int bufferSize)
123 return new FileStream (path, FileMode.Create, FileAccess.ReadWrite,
124 FileShare.None, bufferSize);
127 [MonoLimitation ("FileOptions are ignored")]
128 public static FileStream Create (string path, int bufferSize,
129 FileOptions options)
131 return new FileStream (path, FileMode.Create, FileAccess.ReadWrite,
132 FileShare.None, bufferSize, options);
135 #if !NET_2_1
136 [MonoLimitation ("FileOptions and FileSecurity are ignored")]
137 public static FileStream Create (string path, int bufferSize,
138 FileOptions options,
139 FileSecurity fileSecurity)
141 return new FileStream (path, FileMode.Create, FileAccess.ReadWrite,
142 FileShare.None, bufferSize, options);
144 #endif
146 public static StreamWriter CreateText (string path)
148 return new StreamWriter (path, false);
151 public static void Delete (string path)
153 Path.Validate (path);
154 if (Directory.Exists (path))
155 throw new UnauthorizedAccessException(Locale.GetText ("{0} is a directory", path));
157 string DirName = Path.GetDirectoryName(path);
158 if (DirName != String.Empty && !Directory.Exists (DirName))
159 throw new DirectoryNotFoundException (Locale.GetText ("Could not find a part of the path \"{0}\".", path));
161 SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
163 MonoIOError error;
165 if (!MonoIO.DeleteFile (path, out error)){
166 if (error != MonoIOError.ERROR_FILE_NOT_FOUND)
167 throw MonoIO.GetException (path, error);
171 public static bool Exists (string path)
173 // For security reasons no exceptions are
174 // thrown, only false is returned if there is
175 // any problem with the path or permissions.
176 // Minimizes what information can be
177 // discovered by using this method.
178 if (String.IsNullOrWhiteSpace (path) || path.IndexOfAny(Path.InvalidPathChars) >= 0)
179 return false;
181 // on Moonlight this does not throw but returns false
182 if (!SecurityManager.CheckElevatedPermissions ())
183 return false;
185 MonoIOError error;
186 return MonoIO.ExistsFile (path, out error);
189 #if !NET_2_1
190 public static FileSecurity GetAccessControl (string path)
192 // AccessControlSections.Audit requires special permissions.
193 return GetAccessControl (path,
194 AccessControlSections.Owner |
195 AccessControlSections.Group |
196 AccessControlSections.Access);
199 public static FileSecurity GetAccessControl (string path, AccessControlSections includeSections)
201 return new FileSecurity (path, includeSections);
203 #endif
205 public static FileAttributes GetAttributes (string path)
207 Path.Validate (path);
208 SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
210 MonoIOError error;
211 FileAttributes attrs;
213 attrs = MonoIO.GetFileAttributes (path, out error);
214 if (error != MonoIOError.ERROR_SUCCESS)
215 throw MonoIO.GetException (path, error);
216 return attrs;
219 public static DateTime GetCreationTime (string path)
221 MonoIOStat stat;
222 MonoIOError error;
223 Path.Validate (path);
224 SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
226 if (!MonoIO.GetFileStat (path, out stat, out error)) {
227 if (error == MonoIOError.ERROR_PATH_NOT_FOUND || error == MonoIOError.ERROR_FILE_NOT_FOUND)
228 return DefaultLocalFileTime;
229 else
230 throw new IOException (path);
232 return DateTime.FromFileTime (stat.CreationTime);
235 public static DateTime GetCreationTimeUtc (string path)
237 return GetCreationTime (path).ToUniversalTime ();
240 public static DateTime GetLastAccessTime (string path)
242 MonoIOStat stat;
243 MonoIOError error;
244 Path.Validate (path);
245 SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
247 if (!MonoIO.GetFileStat (path, out stat, out error)) {
248 if (error == MonoIOError.ERROR_PATH_NOT_FOUND || error == MonoIOError.ERROR_FILE_NOT_FOUND)
249 return DefaultLocalFileTime;
250 else
251 throw new IOException (path);
253 return DateTime.FromFileTime (stat.LastAccessTime);
256 public static DateTime GetLastAccessTimeUtc (string path)
258 return GetLastAccessTime (path).ToUniversalTime ();
261 public static DateTime GetLastWriteTime (string path)
263 MonoIOStat stat;
264 MonoIOError error;
265 Path.Validate (path);
266 SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
268 if (!MonoIO.GetFileStat (path, out stat, out error)) {
269 if (error == MonoIOError.ERROR_PATH_NOT_FOUND || error == MonoIOError.ERROR_FILE_NOT_FOUND)
270 return DefaultLocalFileTime;
271 else
272 throw new IOException (path);
274 return DateTime.FromFileTime (stat.LastWriteTime);
277 public static DateTime GetLastWriteTimeUtc (string path)
279 return GetLastWriteTime (path).ToUniversalTime ();
282 public static void Move (string sourceFileName, string destFileName)
284 if (sourceFileName == null)
285 throw new ArgumentNullException ("sourceFileName");
286 if (destFileName == null)
287 throw new ArgumentNullException ("destFileName");
288 if (sourceFileName.Length == 0)
289 throw new ArgumentException ("An empty file name is not valid.", "sourceFileName");
290 if (sourceFileName.Trim ().Length == 0 || sourceFileName.IndexOfAny (Path.InvalidPathChars) != -1)
291 throw new ArgumentException ("The file name is not valid.");
292 if (destFileName.Length == 0)
293 throw new ArgumentException ("An empty file name is not valid.", "destFileName");
294 if (destFileName.Trim ().Length == 0 || destFileName.IndexOfAny (Path.InvalidPathChars) != -1)
295 throw new ArgumentException ("The file name is not valid.");
297 SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
299 MonoIOError error;
300 if (!MonoIO.Exists (sourceFileName, out error))
301 throw new FileNotFoundException (Locale.GetText ("{0} does not exist", sourceFileName), sourceFileName);
303 // Don't check for this error here to allow the runtime
304 // to check if sourceFileName and destFileName are equal.
305 // Comparing sourceFileName and destFileName is not enough.
306 //if (MonoIO.Exists (destFileName, out error))
307 // throw new IOException (Locale.GetText ("{0} already exists", destFileName));
309 string DirName;
310 DirName = Path.GetDirectoryName (destFileName);
311 if (DirName != String.Empty && !Directory.Exists (DirName))
312 throw new DirectoryNotFoundException (Locale.GetText ("Could not find a part of the path."));
314 if (!MonoIO.MoveFile (sourceFileName, destFileName, out error)) {
315 if (error == MonoIOError.ERROR_ALREADY_EXISTS)
316 throw MonoIO.GetException (error);
317 else if (error == MonoIOError.ERROR_SHARING_VIOLATION)
318 throw MonoIO.GetException (sourceFileName, error);
320 throw MonoIO.GetException (error);
324 public static FileStream Open (string path, FileMode mode)
326 return new FileStream (path, mode, mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite, FileShare.None);
329 public static FileStream Open (string path, FileMode mode, FileAccess access)
331 return new FileStream (path, mode, access, FileShare.None);
334 public static FileStream Open (string path, FileMode mode, FileAccess access,
335 FileShare share)
337 return new FileStream (path, mode, access, share);
340 public static FileStream OpenRead (string path)
342 return new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.Read);
345 public static StreamReader OpenText (string path)
347 return new StreamReader (path);
350 public static FileStream OpenWrite (string path)
352 return new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
355 public static void Replace (string sourceFileName,
356 string destinationFileName,
357 string destinationBackupFileName)
359 Replace (sourceFileName, destinationFileName, destinationBackupFileName, false);
362 public static void Replace (string sourceFileName,
363 string destinationFileName,
364 string destinationBackupFileName,
365 bool ignoreMetadataErrors)
367 MonoIOError error;
369 if (sourceFileName == null)
370 throw new ArgumentNullException ("sourceFileName");
371 if (destinationFileName == null)
372 throw new ArgumentNullException ("destinationFileName");
373 if (sourceFileName.Trim ().Length == 0 || sourceFileName.IndexOfAny (Path.InvalidPathChars) != -1)
374 throw new ArgumentException ("sourceFileName");
375 if (destinationFileName.Trim ().Length == 0 || destinationFileName.IndexOfAny (Path.InvalidPathChars) != -1)
376 throw new ArgumentException ("destinationFileName");
378 string fullSource = Path.GetFullPath (sourceFileName);
379 string fullDest = Path.GetFullPath (destinationFileName);
380 if (MonoIO.ExistsDirectory (fullSource, out error))
381 throw new IOException (Locale.GetText ("{0} is a directory", sourceFileName));
382 if (MonoIO.ExistsDirectory (fullDest, out error))
383 throw new IOException (Locale.GetText ("{0} is a directory", destinationFileName));
385 if (!Exists (fullSource))
386 throw new FileNotFoundException (Locale.GetText ("{0} does not exist", sourceFileName),
387 sourceFileName);
388 if (!Exists (fullDest))
389 throw new FileNotFoundException (Locale.GetText ("{0} does not exist", destinationFileName),
390 destinationFileName);
391 if (fullSource == fullDest)
392 throw new IOException (Locale.GetText ("Source and destination arguments are the same file."));
394 string fullBackup = null;
395 if (destinationBackupFileName != null) {
396 if (destinationBackupFileName.Trim ().Length == 0 ||
397 destinationBackupFileName.IndexOfAny (Path.InvalidPathChars) != -1)
398 throw new ArgumentException ("destinationBackupFileName");
400 fullBackup = Path.GetFullPath (destinationBackupFileName);
401 if (MonoIO.ExistsDirectory (fullBackup, out error))
402 throw new IOException (Locale.GetText ("{0} is a directory", destinationBackupFileName));
403 if (fullSource == fullBackup)
404 throw new IOException (Locale.GetText ("Source and backup arguments are the same file."));
405 if (fullDest == fullBackup)
406 throw new IOException (Locale.GetText (
407 "Destination and backup arguments are the same file."));
410 if (!MonoIO.ReplaceFile (fullSource, fullDest, fullBackup,
411 ignoreMetadataErrors, out error)) {
412 throw MonoIO.GetException (error);
416 #if !NET_2_1
417 public static void SetAccessControl (string path,
418 FileSecurity fileSecurity)
420 if (null == fileSecurity)
421 throw new ArgumentNullException ("fileSecurity");
423 fileSecurity.PersistModifications (path);
425 #endif
427 public static void SetAttributes (string path,
428 FileAttributes fileAttributes)
430 MonoIOError error;
431 Path.Validate (path);
433 if (!MonoIO.SetFileAttributes (path, fileAttributes, out error))
434 throw MonoIO.GetException (path, error);
437 public static void SetCreationTime (string path, DateTime creationTime)
439 MonoIOError error;
440 Path.Validate (path);
441 if (!MonoIO.Exists (path, out error))
442 throw MonoIO.GetException (path, error);
443 if (!MonoIO.SetCreationTime (path, creationTime, out error))
444 throw MonoIO.GetException (path, error);
447 public static void SetCreationTimeUtc (string path, DateTime creationTimeUtc)
449 SetCreationTime (path, creationTimeUtc.ToLocalTime ());
452 public static void SetLastAccessTime (string path, DateTime lastAccessTime)
454 MonoIOError error;
455 Path.Validate (path);
456 if (!MonoIO.Exists (path, out error))
457 throw MonoIO.GetException (path, error);
458 if (!MonoIO.SetLastAccessTime (path, lastAccessTime, out error))
459 throw MonoIO.GetException (path, error);
462 public static void SetLastAccessTimeUtc (string path, DateTime lastAccessTimeUtc)
464 SetLastAccessTime (path, lastAccessTimeUtc.ToLocalTime ());
467 public static void SetLastWriteTime (string path,
468 DateTime lastWriteTime)
470 MonoIOError error;
471 Path.Validate (path);
472 if (!MonoIO.Exists (path, out error))
473 throw MonoIO.GetException (path, error);
474 if (!MonoIO.SetLastWriteTime (path, lastWriteTime, out error))
475 throw MonoIO.GetException (path, error);
478 public static void SetLastWriteTimeUtc (string path,
479 DateTime lastWriteTimeUtc)
481 SetLastWriteTime (path, lastWriteTimeUtc.ToLocalTime ());
485 // The documentation for this method is most likely wrong, it
486 // talks about doing a "binary read", but the remarks say
487 // that this "detects the encoding".
489 // This can not detect and do anything useful with the encoding
490 // since the result is a byte [] not a char [].
492 public static byte [] ReadAllBytes (string path)
494 using (FileStream s = OpenRead (path)) {
495 long size = s.Length;
496 // limited to 2GB according to http://msdn.microsoft.com/en-us/library/system.io.file.readallbytes.aspx
497 if (size > Int32.MaxValue)
498 throw new IOException ("Reading more than 2GB with this call is not supported");
500 int pos = 0;
501 int count = (int) size;
502 byte [] result = new byte [size];
503 while (count > 0) {
504 int n = s.Read (result, pos, count);
505 if (n == 0)
506 throw new IOException ("Unexpected end of stream");
507 pos += n;
508 count -= n;
510 return result;
514 public static string [] ReadAllLines (string path)
516 using (StreamReader reader = File.OpenText (path)) {
517 return ReadAllLines (reader);
521 public static string [] ReadAllLines (string path, Encoding encoding)
523 using (StreamReader reader = new StreamReader (path, encoding)) {
524 return ReadAllLines (reader);
528 static string [] ReadAllLines (StreamReader reader)
530 List<string> list = new List<string> ();
531 while (!reader.EndOfStream)
532 list.Add (reader.ReadLine ());
533 return list.ToArray ();
536 public static string ReadAllText (string path)
538 using (StreamReader sr = new StreamReader (path)) {
539 return sr.ReadToEnd ();
543 public static string ReadAllText (string path, Encoding encoding)
545 using (StreamReader sr = new StreamReader (path, encoding)) {
546 return sr.ReadToEnd ();
550 public static void WriteAllBytes (string path, byte [] bytes)
552 using (Stream stream = File.Create (path)) {
553 stream.Write (bytes, 0, bytes.Length);
557 public static void WriteAllLines (string path, string [] contents)
559 using (StreamWriter writer = new StreamWriter (path)) {
560 WriteAllLines (writer, contents);
564 public static void WriteAllLines (string path, string [] contents, Encoding encoding)
566 using (StreamWriter writer = new StreamWriter (path, false, encoding)) {
567 WriteAllLines (writer, contents);
571 static void WriteAllLines (StreamWriter writer, string [] contents)
573 foreach (string line in contents)
574 writer.WriteLine (line);
577 public static void WriteAllText (string path, string contents)
579 WriteAllText (path, contents, Encoding.UTF8Unmarked);
582 public static void WriteAllText (string path, string contents, Encoding encoding)
584 using (StreamWriter sw = new StreamWriter (path, false, encoding)) {
585 sw.Write (contents);
589 static DateTime? defaultLocalFileTime;
590 static DateTime DefaultLocalFileTime {
591 get {
592 if (defaultLocalFileTime == null)
593 defaultLocalFileTime = new DateTime (1601, 1, 1).ToLocalTime ();
595 return defaultLocalFileTime.Value;
600 [MonoLimitation ("File encryption isn't supported (even on NTFS).")]
601 public static void Encrypt (string path)
603 // MS.NET support this only on NTFS file systems, i.e. it's a file-system (not a framework) feature.
604 // otherwise it throws a NotSupportedException (or a PlatformNotSupportedException on older OS).
605 // we throw the same (instead of a NotImplementedException) because most code should already be
606 // handling this exception to work properly.
607 throw new NotSupportedException (Locale.GetText ("File encryption isn't supported on any file system."));
610 [MonoLimitation ("File encryption isn't supported (even on NTFS).")]
611 public static void Decrypt (string path)
613 // MS.NET support this only on NTFS file systems, i.e. it's a file-system (not a framework) feature.
614 // otherwise it throws a NotSupportedException (or a PlatformNotSupportedException on older OS).
615 // we throw the same (instead of a NotImplementedException) because most code should already be
616 // handling this exception to work properly.
617 throw new NotSupportedException (Locale.GetText ("File encryption isn't supported on any file system."));
620 #if NET_4_0
621 public static IEnumerable<string> ReadLines (string path)
623 return ReadLines (File.OpenText (path));
626 public static IEnumerable<string> ReadLines (string path, Encoding encoding)
628 return ReadLines (new StreamReader (path, encoding));
631 // refactored in order to avoid compiler-generated names for Moonlight tools
632 static IEnumerable<string> ReadLines (StreamReader reader)
634 using (reader) {
635 string s;
636 while ((s = reader.ReadLine ()) != null) {
637 yield return s;
642 public static void AppendAllLines (string path, IEnumerable<string> contents)
644 Path.Validate (path);
646 if (contents == null)
647 return;
649 using (TextWriter w = new StreamWriter (path, true)) {
650 foreach (var line in contents)
651 w.WriteLine (line);
655 public static void AppendAllLines (string path, IEnumerable<string> contents, Encoding encoding)
657 Path.Validate (path);
659 if (contents == null)
660 return;
662 using (TextWriter w = new StreamWriter (path, true, encoding)) {
663 foreach (var line in contents)
664 w.WriteLine (line);
668 public static void WriteAllLines (string path, IEnumerable<string> contents)
670 Path.Validate (path);
672 if (contents == null)
673 return;
675 using (TextWriter w = new StreamWriter (path, false)) {
676 foreach (var line in contents)
677 w.WriteLine (line);
681 public static void WriteAllLines (string path, IEnumerable<string> contents, Encoding encoding)
683 Path.Validate (path);
685 if (contents == null)
686 return;
688 using (TextWriter w = new StreamWriter (path, false, encoding)) {
689 foreach (var line in contents)
690 w.WriteLine (line);
693 #endif