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:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
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.
36 using System
.Collections
.Generic
;
37 using System
.Diagnostics
;
38 using System
.Security
;
40 using System
.Runtime
.InteropServices
;
41 using System
.Security
.AccessControl
;
46 public static class File
48 public static void AppendAllText (string path
, string contents
)
50 using (TextWriter w
= new StreamWriter (path
, true)) {
55 public static void AppendAllText (string path
, string contents
, Encoding encoding
)
57 using (TextWriter w
= new StreamWriter (path
, true, encoding
)) {
62 public static StreamWriter
AppendText (string path
)
64 return new StreamWriter (path
, true);
67 public static void Copy (string sourceFileName
, string destFileName
)
69 Copy (sourceFileName
, destFileName
, false);
72 public static void Copy (string sourceFileName
, string destFileName
, bool overwrite
)
76 if (sourceFileName
== null)
77 throw new ArgumentNullException ("sourceFileName");
78 if (destFileName
== null)
79 throw new ArgumentNullException ("destFileName");
80 if (sourceFileName
.Length
== 0)
81 throw new ArgumentException ("An empty file name is not valid.", "sourceFileName");
82 if (sourceFileName
.Trim ().Length
== 0 || sourceFileName
.IndexOfAny (Path
.InvalidPathChars
) != -1)
83 throw new ArgumentException ("The file name is not valid.");
84 if (destFileName
.Length
== 0)
85 throw new ArgumentException ("An empty file name is not valid.", "destFileName");
86 if (destFileName
.Trim ().Length
== 0 || destFileName
.IndexOfAny (Path
.InvalidPathChars
) != -1)
87 throw new ArgumentException ("The file name is not valid.");
89 SecurityManager
.EnsureElevatedPermissions (); // this is a no-op outside moonlight
91 if (!MonoIO
.Exists (sourceFileName
, out error
))
92 throw new FileNotFoundException (Locale
.GetText ("{0} does not exist", sourceFileName
), sourceFileName
);
93 if ((GetAttributes (sourceFileName
) & FileAttributes
.Directory
) == FileAttributes
.Directory
)
94 throw new ArgumentException (Locale
.GetText ("{0} is a directory", sourceFileName
));
96 if (MonoIO
.Exists (destFileName
, out error
)) {
97 if ((GetAttributes (destFileName
) & FileAttributes
.Directory
) == FileAttributes
.Directory
)
98 throw new ArgumentException (Locale
.GetText ("{0} is a directory", destFileName
));
100 throw new IOException (Locale
.GetText ("{0} already exists", destFileName
));
103 string DirName
= Path
.GetDirectoryName (destFileName
);
104 if (DirName
!= String
.Empty
&& !Directory
.Exists (DirName
))
105 throw new DirectoryNotFoundException (Locale
.GetText ("Destination directory not found: {0}",DirName
));
107 if (!MonoIO
.CopyFile (sourceFileName
, destFileName
, overwrite
, out error
)) {
108 string p
= Locale
.GetText ("{0}\" or \"{1}", sourceFileName
, destFileName
);
109 throw MonoIO
.GetException (p
, error
);
113 internal static String
InternalCopy (String sourceFileName
, String destFileName
, bool overwrite
, bool checkHost
)
115 String fullSourceFileName
= Path
.GetFullPathInternal(sourceFileName
);
116 String fullDestFileName
= Path
.GetFullPathInternal(destFileName
);
120 if (!MonoIO
.CopyFile (fullSourceFileName
, fullDestFileName
, overwrite
, out error
)) {
121 string p
= Locale
.GetText ("{0}\" or \"{1}", sourceFileName
, destFileName
);
122 throw MonoIO
.GetException (p
, error
);
125 return fullDestFileName
;
128 public static FileStream
Create (string path
)
130 return Create (path
, 8192);
133 public static FileStream
Create (string path
, int bufferSize
)
135 return new FileStream (path
, FileMode
.Create
, FileAccess
.ReadWrite
,
136 FileShare
.None
, bufferSize
);
139 [MonoLimitation ("FileOptions are ignored")]
140 public static FileStream
Create (string path
, int bufferSize
,
143 return new FileStream (path
, FileMode
.Create
, FileAccess
.ReadWrite
,
144 FileShare
.None
, bufferSize
, options
);
147 [MonoLimitation ("FileOptions and FileSecurity are ignored")]
148 public static FileStream
Create (string path
, int bufferSize
,
150 FileSecurity fileSecurity
)
152 return new FileStream (path
, FileMode
.Create
, FileAccess
.ReadWrite
,
153 FileShare
.None
, bufferSize
, options
);
156 public static StreamWriter
CreateText (string path
)
158 return new StreamWriter (path
, false);
161 public static void Delete (string path
)
163 Path
.Validate (path
);
164 if (Directory
.Exists (path
))
165 throw new UnauthorizedAccessException(Locale
.GetText ("{0} is a directory", path
));
167 string DirName
= Path
.GetDirectoryName(path
);
168 if (DirName
!= String
.Empty
&& !Directory
.Exists (DirName
))
169 throw new DirectoryNotFoundException (Locale
.GetText ("Could not find a part of the path \"{0}\".", path
));
171 SecurityManager
.EnsureElevatedPermissions (); // this is a no-op outside moonlight
175 if (!MonoIO
.DeleteFile (path
, out error
)){
176 if (error
!= MonoIOError
.ERROR_FILE_NOT_FOUND
)
177 throw MonoIO
.GetException (path
, error
);
181 public static bool Exists (string path
)
183 // For security reasons no exceptions are
184 // thrown, only false is returned if there is
185 // any problem with the path or permissions.
186 // Minimizes what information can be
187 // discovered by using this method.
188 if (String
.IsNullOrWhiteSpace (path
) || path
.IndexOfAny(Path
.InvalidPathChars
) >= 0)
191 // on Moonlight this does not throw but returns false
192 if (!SecurityManager
.CheckElevatedPermissions ())
196 return MonoIO
.ExistsFile (path
, out error
);
199 public static FileSecurity
GetAccessControl (string path
)
201 // AccessControlSections.Audit requires special permissions.
202 return GetAccessControl (path
,
203 AccessControlSections
.Owner
|
204 AccessControlSections
.Group
|
205 AccessControlSections
.Access
);
208 public static FileSecurity
GetAccessControl (string path
, AccessControlSections includeSections
)
210 return new FileSecurity (path
, includeSections
);
213 public static FileAttributes
GetAttributes (string path
)
215 Path
.Validate (path
);
216 SecurityManager
.EnsureElevatedPermissions (); // this is a no-op outside moonlight
219 FileAttributes attrs
;
221 attrs
= MonoIO
.GetFileAttributes (path
, out error
);
222 if (error
!= MonoIOError
.ERROR_SUCCESS
)
223 throw MonoIO
.GetException (path
, error
);
227 public static DateTime
GetCreationTime (string path
)
231 Path
.Validate (path
);
232 SecurityManager
.EnsureElevatedPermissions (); // this is a no-op outside moonlight
234 if (!MonoIO
.GetFileStat (path
, out stat
, out error
)) {
235 if (error
== MonoIOError
.ERROR_PATH_NOT_FOUND
|| error
== MonoIOError
.ERROR_FILE_NOT_FOUND
)
236 return DefaultLocalFileTime
;
238 throw new IOException (path
);
240 return DateTime
.FromFileTime (stat
.CreationTime
);
243 public static DateTime
GetCreationTimeUtc (string path
)
245 return GetCreationTime (path
).ToUniversalTime ();
248 public static DateTime
GetLastAccessTime (string path
)
252 Path
.Validate (path
);
253 SecurityManager
.EnsureElevatedPermissions (); // this is a no-op outside moonlight
255 if (!MonoIO
.GetFileStat (path
, out stat
, out error
)) {
256 if (error
== MonoIOError
.ERROR_PATH_NOT_FOUND
|| error
== MonoIOError
.ERROR_FILE_NOT_FOUND
)
257 return DefaultLocalFileTime
;
259 throw new IOException (path
);
261 return DateTime
.FromFileTime (stat
.LastAccessTime
);
264 public static DateTime
GetLastAccessTimeUtc (string path
)
266 return GetLastAccessTime (path
).ToUniversalTime ();
269 public static DateTime
GetLastWriteTime (string path
)
273 Path
.Validate (path
);
274 SecurityManager
.EnsureElevatedPermissions (); // this is a no-op outside moonlight
276 if (!MonoIO
.GetFileStat (path
, out stat
, out error
)) {
277 if (error
== MonoIOError
.ERROR_PATH_NOT_FOUND
|| error
== MonoIOError
.ERROR_FILE_NOT_FOUND
)
278 return DefaultLocalFileTime
;
280 throw new IOException (path
);
282 return DateTime
.FromFileTime (stat
.LastWriteTime
);
285 public static DateTime
GetLastWriteTimeUtc (string path
)
287 return GetLastWriteTime (path
).ToUniversalTime ();
290 public static void Move (string sourceFileName
, string destFileName
)
292 if (sourceFileName
== null)
293 throw new ArgumentNullException ("sourceFileName");
294 if (destFileName
== null)
295 throw new ArgumentNullException ("destFileName");
296 if (sourceFileName
.Length
== 0)
297 throw new ArgumentException ("An empty file name is not valid.", "sourceFileName");
298 if (sourceFileName
.Trim ().Length
== 0 || sourceFileName
.IndexOfAny (Path
.InvalidPathChars
) != -1)
299 throw new ArgumentException ("The file name is not valid.");
300 if (destFileName
.Length
== 0)
301 throw new ArgumentException ("An empty file name is not valid.", "destFileName");
302 if (destFileName
.Trim ().Length
== 0 || destFileName
.IndexOfAny (Path
.InvalidPathChars
) != -1)
303 throw new ArgumentException ("The file name is not valid.");
305 SecurityManager
.EnsureElevatedPermissions (); // this is a no-op outside moonlight
308 if (!MonoIO
.Exists (sourceFileName
, out error
))
309 throw new FileNotFoundException (Locale
.GetText ("{0} does not exist", sourceFileName
), sourceFileName
);
311 // Don't check for this error here to allow the runtime
312 // to check if sourceFileName and destFileName are equal.
313 // Comparing sourceFileName and destFileName is not enough.
314 //if (MonoIO.Exists (destFileName, out error))
315 // throw new IOException (Locale.GetText ("{0} already exists", destFileName));
318 DirName
= Path
.GetDirectoryName (destFileName
);
319 if (DirName
!= String
.Empty
&& !Directory
.Exists (DirName
))
320 throw new DirectoryNotFoundException (Locale
.GetText ("Could not find a part of the path."));
322 if (!MonoIO
.MoveFile (sourceFileName
, destFileName
, out error
)) {
323 if (error
== MonoIOError
.ERROR_ALREADY_EXISTS
)
324 throw MonoIO
.GetException (error
);
325 else if (error
== MonoIOError
.ERROR_SHARING_VIOLATION
)
326 throw MonoIO
.GetException (sourceFileName
, error
);
328 throw MonoIO
.GetException (error
);
332 public static FileStream
Open (string path
, FileMode mode
)
334 return new FileStream (path
, mode
, mode
== FileMode
.Append
? FileAccess
.Write
: FileAccess
.ReadWrite
, FileShare
.None
);
337 public static FileStream
Open (string path
, FileMode mode
, FileAccess access
)
339 return new FileStream (path
, mode
, access
, FileShare
.None
);
342 public static FileStream
Open (string path
, FileMode mode
, FileAccess access
,
345 return new FileStream (path
, mode
, access
, share
);
348 public static FileStream
OpenRead (string path
)
350 return new FileStream (path
, FileMode
.Open
, FileAccess
.Read
, FileShare
.Read
);
353 public static StreamReader
OpenText (string path
)
355 return new StreamReader (path
);
358 public static FileStream
OpenWrite (string path
)
360 return new FileStream(path
, FileMode
.OpenOrCreate
, FileAccess
.Write
, FileShare
.None
);
363 public static void Replace (string sourceFileName
,
364 string destinationFileName
,
365 string destinationBackupFileName
)
367 Replace (sourceFileName
, destinationFileName
, destinationBackupFileName
, false);
370 public static void Replace (string sourceFileName
,
371 string destinationFileName
,
372 string destinationBackupFileName
,
373 bool ignoreMetadataErrors
)
377 if (sourceFileName
== null)
378 throw new ArgumentNullException ("sourceFileName");
379 if (destinationFileName
== null)
380 throw new ArgumentNullException ("destinationFileName");
381 if (sourceFileName
.Trim ().Length
== 0 || sourceFileName
.IndexOfAny (Path
.InvalidPathChars
) != -1)
382 throw new ArgumentException ("sourceFileName");
383 if (destinationFileName
.Trim ().Length
== 0 || destinationFileName
.IndexOfAny (Path
.InvalidPathChars
) != -1)
384 throw new ArgumentException ("destinationFileName");
386 string fullSource
= Path
.GetFullPath (sourceFileName
);
387 string fullDest
= Path
.GetFullPath (destinationFileName
);
388 if (MonoIO
.ExistsDirectory (fullSource
, out error
))
389 throw new IOException (Locale
.GetText ("{0} is a directory", sourceFileName
));
390 if (MonoIO
.ExistsDirectory (fullDest
, out error
))
391 throw new IOException (Locale
.GetText ("{0} is a directory", destinationFileName
));
393 if (!Exists (fullSource
))
394 throw new FileNotFoundException (Locale
.GetText ("{0} does not exist", sourceFileName
),
396 if (!Exists (fullDest
))
397 throw new FileNotFoundException (Locale
.GetText ("{0} does not exist", destinationFileName
),
398 destinationFileName
);
399 if (fullSource
== fullDest
)
400 throw new IOException (Locale
.GetText ("Source and destination arguments are the same file."));
402 string fullBackup
= null;
403 if (destinationBackupFileName
!= null) {
404 if (destinationBackupFileName
.Trim ().Length
== 0 ||
405 destinationBackupFileName
.IndexOfAny (Path
.InvalidPathChars
) != -1)
406 throw new ArgumentException ("destinationBackupFileName");
408 fullBackup
= Path
.GetFullPath (destinationBackupFileName
);
409 if (MonoIO
.ExistsDirectory (fullBackup
, out error
))
410 throw new IOException (Locale
.GetText ("{0} is a directory", destinationBackupFileName
));
411 if (fullSource
== fullBackup
)
412 throw new IOException (Locale
.GetText ("Source and backup arguments are the same file."));
413 if (fullDest
== fullBackup
)
414 throw new IOException (Locale
.GetText (
415 "Destination and backup arguments are the same file."));
418 var attrs
= GetAttributes (fullDest
);
420 // TODO: Should be done in wapi, win32 api handles this already
421 if ((attrs
& FileAttributes
.ReadOnly
) != 0)
422 throw MonoIO
.GetException (MonoIOError
.ERROR_ACCESS_DENIED
);
424 if (!MonoIO
.ReplaceFile (fullSource
, fullDest
, fullBackup
,
425 ignoreMetadataErrors
, out error
)) {
426 throw MonoIO
.GetException (error
);
430 public static void SetAccessControl (string path
,
431 FileSecurity fileSecurity
)
433 if (null == fileSecurity
)
434 throw new ArgumentNullException ("fileSecurity");
436 fileSecurity
.PersistModifications (path
);
439 public static void SetAttributes (string path
,
440 FileAttributes fileAttributes
)
443 Path
.Validate (path
);
445 if (!MonoIO
.SetFileAttributes (path
, fileAttributes
, out error
))
446 throw MonoIO
.GetException (path
, error
);
449 public static void SetCreationTime (string path
, DateTime creationTime
)
452 Path
.Validate (path
);
453 if (!MonoIO
.Exists (path
, out error
))
454 throw MonoIO
.GetException (path
, error
);
455 if (!MonoIO
.SetCreationTime (path
, creationTime
, out error
))
456 throw MonoIO
.GetException (path
, error
);
459 public static void SetCreationTimeUtc (string path
, DateTime creationTimeUtc
)
461 SetCreationTime (path
, creationTimeUtc
.ToLocalTime ());
464 public static void SetLastAccessTime (string path
, DateTime lastAccessTime
)
467 Path
.Validate (path
);
468 if (!MonoIO
.Exists (path
, out error
))
469 throw MonoIO
.GetException (path
, error
);
470 if (!MonoIO
.SetLastAccessTime (path
, lastAccessTime
, out error
))
471 throw MonoIO
.GetException (path
, error
);
474 public static void SetLastAccessTimeUtc (string path
, DateTime lastAccessTimeUtc
)
476 SetLastAccessTime (path
, lastAccessTimeUtc
.ToLocalTime ());
479 public static void SetLastWriteTime (string path
,
480 DateTime lastWriteTime
)
483 Path
.Validate (path
);
484 if (!MonoIO
.Exists (path
, out error
))
485 throw MonoIO
.GetException (path
, error
);
486 if (!MonoIO
.SetLastWriteTime (path
, lastWriteTime
, out error
))
487 throw MonoIO
.GetException (path
, error
);
490 public static void SetLastWriteTimeUtc (string path
,
491 DateTime lastWriteTimeUtc
)
493 SetLastWriteTime (path
, lastWriteTimeUtc
.ToLocalTime ());
497 // The documentation for this method is most likely wrong, it
498 // talks about doing a "binary read", but the remarks say
499 // that this "detects the encoding".
501 // This can not detect and do anything useful with the encoding
502 // since the result is a byte [] not a char [].
504 public static byte [] ReadAllBytes (string path
)
506 using (FileStream s
= OpenRead (path
)) {
507 long size
= s
.Length
;
508 // limited to 2GB according to http://msdn.microsoft.com/en-us/library/system.io.file.readallbytes.aspx
509 if (size
> Int32
.MaxValue
)
510 throw new IOException ("Reading more than 2GB with this call is not supported");
513 int count
= (int) size
;
514 byte [] result
= new byte [size
];
516 int n
= s
.Read (result
, pos
, count
);
518 throw new IOException ("Unexpected end of stream");
526 public static string [] ReadAllLines (string path
)
528 using (StreamReader reader
= File
.OpenText (path
)) {
529 return ReadAllLines (reader
);
533 public static string [] ReadAllLines (string path
, Encoding encoding
)
535 using (StreamReader reader
= new StreamReader (path
, encoding
)) {
536 return ReadAllLines (reader
);
540 static string [] ReadAllLines (StreamReader reader
)
542 List
<string> list
= new List
<string> ();
543 while (!reader
.EndOfStream
)
544 list
.Add (reader
.ReadLine ());
545 return list
.ToArray ();
548 public static string ReadAllText (string path
)
550 using (StreamReader sr
= new StreamReader (path
)) {
551 return sr
.ReadToEnd ();
555 public static string ReadAllText (string path
, Encoding encoding
)
557 using (StreamReader sr
= new StreamReader (path
, encoding
)) {
558 return sr
.ReadToEnd ();
562 public static void WriteAllBytes (string path
, byte [] bytes
)
564 using (Stream stream
= File
.Create (path
)) {
565 stream
.Write (bytes
, 0, bytes
.Length
);
569 public static void WriteAllLines (string path
, string [] contents
)
571 using (StreamWriter writer
= new StreamWriter (path
)) {
572 WriteAllLines (writer
, contents
);
576 public static void WriteAllLines (string path
, string [] contents
, Encoding encoding
)
578 using (StreamWriter writer
= new StreamWriter (path
, false, encoding
)) {
579 WriteAllLines (writer
, contents
);
583 static void WriteAllLines (StreamWriter writer
, string [] contents
)
585 foreach (string line
in contents
)
586 writer
.WriteLine (line
);
589 public static void WriteAllText (string path
, string contents
)
591 WriteAllText (path
, contents
, EncodingHelper
.UTF8Unmarked
);
594 public static void WriteAllText (string path
, string contents
, Encoding encoding
)
596 using (StreamWriter sw
= new StreamWriter (path
, false, encoding
)) {
601 static DateTime
? defaultLocalFileTime
;
602 static DateTime DefaultLocalFileTime
{
604 if (defaultLocalFileTime
== null)
605 defaultLocalFileTime
= new DateTime (1601, 1, 1).ToLocalTime ();
607 return defaultLocalFileTime
.Value
;
612 [MonoLimitation ("File encryption isn't supported (even on NTFS).")]
613 public static void Encrypt (string path
)
615 // MS.NET support this only on NTFS file systems, i.e. it's a file-system (not a framework) feature.
616 // otherwise it throws a NotSupportedException (or a PlatformNotSupportedException on older OS).
617 // we throw the same (instead of a NotImplementedException) because most code should already be
618 // handling this exception to work properly.
619 throw new NotSupportedException (Locale
.GetText ("File encryption isn't supported on any file system."));
622 [MonoLimitation ("File encryption isn't supported (even on NTFS).")]
623 public static void Decrypt (string path
)
625 // MS.NET support this only on NTFS file systems, i.e. it's a file-system (not a framework) feature.
626 // otherwise it throws a NotSupportedException (or a PlatformNotSupportedException on older OS).
627 // we throw the same (instead of a NotImplementedException) because most code should already be
628 // handling this exception to work properly.
629 throw new NotSupportedException (Locale
.GetText ("File encryption isn't supported on any file system."));
632 public static IEnumerable
<string> ReadLines (string path
)
634 return ReadLines (File
.OpenText (path
));
637 public static IEnumerable
<string> ReadLines (string path
, Encoding encoding
)
639 return ReadLines (new StreamReader (path
, encoding
));
642 // refactored in order to avoid compiler-generated names for Moonlight tools
643 static IEnumerable
<string> ReadLines (StreamReader reader
)
647 while ((s
= reader
.ReadLine ()) != null) {
653 public static void AppendAllLines (string path
, IEnumerable
<string> contents
)
655 Path
.Validate (path
);
657 if (contents
== null)
660 using (TextWriter w
= new StreamWriter (path
, true)) {
661 foreach (var line
in contents
)
666 public static void AppendAllLines (string path
, IEnumerable
<string> contents
, Encoding encoding
)
668 Path
.Validate (path
);
670 if (contents
== null)
673 using (TextWriter w
= new StreamWriter (path
, true, encoding
)) {
674 foreach (var line
in contents
)
679 public static void WriteAllLines (string path
, IEnumerable
<string> contents
)
681 Path
.Validate (path
);
683 if (contents
== null)
686 using (TextWriter w
= new StreamWriter (path
, false)) {
687 foreach (var line
in contents
)
692 public static void WriteAllLines (string path
, IEnumerable
<string> contents
, Encoding encoding
)
694 Path
.Validate (path
);
696 if (contents
== null)
699 using (TextWriter w
= new StreamWriter (path
, false, encoding
)) {
700 foreach (var line
in contents
)
705 internal static int FillAttributeInfo (String path
, ref MonoIOStat data
, bool tryagain
, bool returnErrorOnNotFound
)
708 throw new NotImplementedException ();
711 MonoIO
.GetFileStat (path
, out data
, out error
);
713 if (!returnErrorOnNotFound
&& (error
== MonoIOError
.ERROR_FILE_NOT_FOUND
|| error
== MonoIOError
.ERROR_PATH_NOT_FOUND
|| error
== MonoIOError
.ERROR_NOT_READY
)) {
714 data
= default (MonoIOStat
);
715 data
.fileAttributes
= (FileAttributes
) (-1);
721 #region Copied from corefx
723 internal static DateTimeOffset
GetUtcDateTimeOffset(DateTime dateTime
)
725 // File and Directory UTC APIs treat a DateTimeKind.Unspecified as UTC whereas
726 // ToUniversalTime treats this as local.
727 if (dateTime
.Kind
== DateTimeKind
.Unspecified
)
729 return DateTime
.SpecifyKind(dateTime
, DateTimeKind
.Utc
);
732 return dateTime
.ToUniversalTime();