//
// Copyright 2002 Ximian, Inc. http://www.ximian.com
// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
-// Copyright (C) 2004, 2006 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004, 2006, 2010 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
//
using System;
-using System.Text;
-#if NET_2_0
using System.Collections.Generic;
+using System.Diagnostics;
+using System.Security;
+using System.Text;
using System.Runtime.InteropServices;
+
+#if !NET_2_1
using System.Security.AccessControl;
#endif
namespace System.IO
{
-#if NET_2_0
[ComVisible (true)]
-#endif
- public
-#if NET_2_0
- static
-#else
- sealed
-#endif
- class File
+ public static class File
{
-
-#if !NET_2_0
- private File () {}
-#endif
-
-#if NET_2_0
public static void AppendAllText (string path, string contents)
{
using (TextWriter w = new StreamWriter (path, true)) {
w.Write (contents);
}
}
-#endif
public static StreamWriter AppendText (string path)
{
if (destFileName.Trim ().Length == 0 || destFileName.IndexOfAny (Path.InvalidPathChars) != -1)
throw new ArgumentException ("The file name is not valid.");
+ SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
+
if (!MonoIO.Exists (sourceFileName, out error))
throw new FileNotFoundException (Locale.GetText ("{0} does not exist", sourceFileName), sourceFileName);
if ((GetAttributes (sourceFileName) & FileAttributes.Directory) == FileAttributes.Directory)
public static FileStream Create (string path)
{
- return Create (path, 8192, FileOptions.None, null);
+ return Create (path, 8192);
}
public static FileStream Create (string path, int bufferSize)
{
- return Create (path, bufferSize, FileOptions.None, null);
+ return new FileStream (path, FileMode.Create, FileAccess.ReadWrite,
+ FileShare.None, bufferSize);
}
-#if NET_2_0
- [MonoTODO ("options not implemented")]
+#if !NET_2_1
+ [MonoLimitation ("FileOptions are ignored")]
public static FileStream Create (string path, int bufferSize,
FileOptions options)
{
return Create (path, bufferSize, options, null);
}
- [MonoTODO ("options and fileSecurity not implemented")]
+ [MonoLimitation ("FileOptions and FileSecurity are ignored")]
public static FileStream Create (string path, int bufferSize,
FileOptions options,
FileSecurity fileSecurity)
-#else
- private static FileStream Create (string path, int bufferSize,
- FileOptions options,
- object fileSecurity)
-#endif
{
-#if NET_2_0
return new FileStream (path, FileMode.Create, FileAccess.ReadWrite,
FileShare.None, bufferSize, options);
-#else
- return new FileStream (path, FileMode.Create, FileAccess.ReadWrite,
- FileShare.None, bufferSize);
-#endif
}
+#endif
public static StreamWriter CreateText (string path)
{
public static void Delete (string path)
{
- if (path == null)
- throw new ArgumentNullException("path");
- if (path.Trim().Length == 0 || path.IndexOfAny(Path.InvalidPathChars) >= 0)
- throw new ArgumentException("path");
+ Path.Validate (path);
if (Directory.Exists (path))
throw new UnauthorizedAccessException(Locale.GetText ("{0} is a directory", path));
if (DirName != String.Empty && !Directory.Exists (DirName))
throw new DirectoryNotFoundException (Locale.GetText ("Could not find a part of the path \"{0}\".", path));
+ SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
+
MonoIOError error;
if (!MonoIO.DeleteFile (path, out error)){
// any problem with the path or permissions.
// Minimizes what information can be
// discovered by using this method.
- if (path == null || path.Trim().Length == 0
- || path.IndexOfAny(Path.InvalidPathChars) >= 0) {
+ if (String.IsNullOrWhiteSpace (path) || path.IndexOfAny(Path.InvalidPathChars) >= 0)
+ return false;
+
+ // on Moonlight this does not throw but returns false
+ if (!SecurityManager.CheckElevatedPermissions ())
return false;
- }
MonoIOError error;
return MonoIO.ExistsFile (path, out error);
}
-#if NET_2_0
+#if !NET_2_1
public static FileSecurity GetAccessControl (string path)
{
throw new NotImplementedException ();
public static FileAttributes GetAttributes (string path)
{
- if (path == null)
- throw new ArgumentNullException("path");
- if (path.Trim ().Length == 0)
- throw new ArgumentException (Locale.GetText ("Path is empty"));
- if (path.IndexOfAny (Path.InvalidPathChars) >= 0)
- throw new ArgumentException (Locale.GetText ("Path contains invalid chars"));
+ Path.Validate (path);
+ SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
MonoIOError error;
FileAttributes attrs;
{
MonoIOStat stat;
MonoIOError error;
- CheckPathExceptions (path);
+ Path.Validate (path);
+ SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
if (!MonoIO.GetFileStat (path, out stat, out error)) {
-#if NET_2_0
if (error == MonoIOError.ERROR_PATH_NOT_FOUND || error == MonoIOError.ERROR_FILE_NOT_FOUND)
return DefaultLocalFileTime;
else
throw new IOException (path);
-#else
- throw CreatePartOfPathNotFoundException (path);
-#endif
}
return DateTime.FromFileTime (stat.CreationTime);
}
{
MonoIOStat stat;
MonoIOError error;
- CheckPathExceptions (path);
+ Path.Validate (path);
+ SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
if (!MonoIO.GetFileStat (path, out stat, out error)) {
-#if NET_2_0
if (error == MonoIOError.ERROR_PATH_NOT_FOUND || error == MonoIOError.ERROR_FILE_NOT_FOUND)
return DefaultLocalFileTime;
else
throw new IOException (path);
-#else
- throw CreatePartOfPathNotFoundException (path);
-#endif
}
return DateTime.FromFileTime (stat.LastAccessTime);
}
{
MonoIOStat stat;
MonoIOError error;
- CheckPathExceptions (path);
+ Path.Validate (path);
+ SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
if (!MonoIO.GetFileStat (path, out stat, out error)) {
-#if NET_2_0
if (error == MonoIOError.ERROR_PATH_NOT_FOUND || error == MonoIOError.ERROR_FILE_NOT_FOUND)
return DefaultLocalFileTime;
else
throw new IOException (path);
-#else
- throw CreatePartOfPathNotFoundException (path);
-#endif
}
return DateTime.FromFileTime (stat.LastWriteTime);
}
public static void Move (string sourceFileName, string destFileName)
{
- MonoIOError error;
-
if (sourceFileName == null)
throw new ArgumentNullException ("sourceFileName");
if (destFileName == null)
throw new ArgumentException ("An empty file name is not valid.", "destFileName");
if (destFileName.Trim ().Length == 0 || destFileName.IndexOfAny (Path.InvalidPathChars) != -1)
throw new ArgumentException ("The file name is not valid.");
+
+ SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
+
+ MonoIOError error;
if (!MonoIO.Exists (sourceFileName, out error))
throw new FileNotFoundException (Locale.GetText ("{0} does not exist", sourceFileName), sourceFileName);
string DirName;
DirName = Path.GetDirectoryName (destFileName);
if (DirName != String.Empty && !Directory.Exists (DirName))
-#if NET_2_0
throw new DirectoryNotFoundException (Locale.GetText ("Could not find a part of the path."));
-#else
- throw new DirectoryNotFoundException (Locale.GetText ("Could not find a part of the path '{0}'.", destFileName));
-#endif
if (!MonoIO.MoveFile (sourceFileName, destFileName, out error)) {
if (error == MonoIOError.ERROR_ALREADY_EXISTS)
return new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
}
-#if NET_2_0
public static void Replace (string sourceFileName,
string destinationFileName,
string destinationBackupFileName)
throw MonoIO.GetException (error);
}
}
-
+
+#if !NET_2_1
public static void SetAccessControl (string path,
FileSecurity fileSecurity)
{
FileAttributes fileAttributes)
{
MonoIOError error;
- CheckPathExceptions (path);
+ Path.Validate (path);
if (!MonoIO.SetFileAttributes (path, fileAttributes, out error))
throw MonoIO.GetException (path, error);
public static void SetCreationTime (string path, DateTime creationTime)
{
MonoIOError error;
- CheckPathExceptions (path);
+ Path.Validate (path);
if (!MonoIO.Exists (path, out error))
throw MonoIO.GetException (path, error);
if (!MonoIO.SetCreationTime (path, creationTime, out error))
public static void SetLastAccessTime (string path, DateTime lastAccessTime)
{
MonoIOError error;
- CheckPathExceptions (path);
+ Path.Validate (path);
if (!MonoIO.Exists (path, out error))
throw MonoIO.GetException (path, error);
if (!MonoIO.SetLastAccessTime (path, lastAccessTime, out error))
DateTime lastWriteTime)
{
MonoIOError error;
- CheckPathExceptions (path);
+ Path.Validate (path);
if (!MonoIO.Exists (path, out error))
throw MonoIO.GetException (path, error);
if (!MonoIO.SetLastWriteTime (path, lastWriteTime, out error))
SetLastWriteTime (path, lastWriteTimeUtc.ToLocalTime ());
}
- #region Private
-
- private static void CheckPathExceptions (string path)
- {
- if (path == null)
- throw new System.ArgumentNullException("path");
- if (path.Length == 0)
- throw new System.ArgumentException(Locale.GetText ("Path is empty"));
- if (path.Trim().Length == 0)
- throw new ArgumentException (Locale.GetText ("Path is empty"));
- if (path.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException (Locale.GetText ("Path contains invalid chars"));
- }
-
- private static IOException CreatePartOfPathNotFoundException (string path)
- {
- string msg = Locale.GetText ("Part of the path \"{0}\" could not be found.", path);
- return new IOException (msg);
- }
-
- #endregion
-
-#if NET_2_0
//
// The documentation for this method is most likely wrong, it
// talks about doing a "binary read", but the remarks say
//
public static byte [] ReadAllBytes (string path)
{
- using (FileStream s = Open (path, FileMode.Open, FileAccess.Read, FileShare.Read)){
+ using (FileStream s = OpenRead (path)) {
long size = s.Length;
-
- //
- // Is this worth supporting?
- //
+ // limited to 2GB according to http://msdn.microsoft.com/en-us/library/system.io.file.readallbytes.aspx
if (size > Int32.MaxValue)
- throw new ArgumentException ("Reading more than 4gigs with this call is not supported");
-
- byte [] result = new byte [s.Length];
-
- s.Read (result, 0, (int) size);
-
+ throw new IOException ("Reading more than 2GB with this call is not supported");
+
+ int pos = 0;
+ int count = (int) size;
+ byte [] result = new byte [size];
+ while (count > 0) {
+ int n = s.Read (result, pos, count);
+ if (n == 0)
+ throw new IOException ("Unexpected end of stream");
+ pos += n;
+ count -= n;
+ }
return result;
}
}
public static string ReadAllText (string path)
{
- return ReadAllText (path, Encoding.UTF8Unmarked);
+ using (StreamReader sr = new StreamReader (path)) {
+ return sr.ReadToEnd ();
+ }
}
public static string ReadAllText (string path, Encoding encoding)
// handling this exception to work properly.
throw new NotSupportedException (Locale.GetText ("File encryption isn't supported on any file system."));
}
+
+#if MOONLIGHT || NET_4_0
+ public static IEnumerable<string> ReadLines (string path)
+ {
+ return ReadLines (File.OpenText (path));
+ }
+
+ public static IEnumerable<string> ReadLines (string path, Encoding encoding)
+ {
+ return ReadLines (new StreamReader (path, encoding));
+ }
+
+ // refactored in order to avoid compiler-generated names for Moonlight tools
+ static IEnumerable<string> ReadLines (StreamReader reader)
+ {
+ using (reader) {
+ string s;
+ while ((s = reader.ReadLine ()) != null) {
+ yield return s;
+ }
+ }
+ }
+
+ public static void AppendAllLines (string path, IEnumerable<string> contents)
+ {
+ Path.Validate (path);
+
+ if (contents == null)
+ return;
+
+ using (TextWriter w = new StreamWriter (path, true)) {
+ foreach (var line in contents)
+ w.Write (line);
+ }
+ }
+
+ public static void AppendAllLines (string path, IEnumerable<string> contents, Encoding encoding)
+ {
+ Path.Validate (path);
+
+ if (contents == null)
+ return;
+
+ using (TextWriter w = new StreamWriter (path, true, encoding)) {
+ foreach (var line in contents)
+ w.Write (line);
+ }
+ }
+
+ public static void WriteAllLines (string path, IEnumerable<string> contents)
+ {
+ Path.Validate (path);
+
+ if (contents == null)
+ return;
+
+ using (TextWriter w = new StreamWriter (path, false)) {
+ foreach (var line in contents)
+ w.Write (line);
+ }
+ }
+
+ public static void WriteAllLines (string path, IEnumerable<string> contents, Encoding encoding)
+ {
+ Path.Validate (path);
+
+ if (contents == null)
+ return;
+
+ using (TextWriter w = new StreamWriter (path, false, encoding)) {
+ foreach (var line in contents)
+ w.Write (line);
+ }
+ }
#endif
}
}