File.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. //
  2. // System.IO.File.cs
  3. //
  4. //
  5. // Authors:
  6. // Miguel de Icaza ([email protected])
  7. // Jim Richardson ([email protected])
  8. // Dan Lewis ([email protected])
  9. // Ville Palo ([email protected])
  10. //
  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)
  14. //
  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.
  33. //
  34. using System;
  35. using System.Collections.Generic;
  36. using System.Diagnostics;
  37. using System.Security;
  38. using System.Text;
  39. using System.Runtime.InteropServices;
  40. using System.Security.AccessControl;
  41. namespace System.IO
  42. {
  43. [ComVisible (true)]
  44. public static class File
  45. {
  46. public static void AppendAllText (string path, string contents)
  47. {
  48. using (TextWriter w = new StreamWriter (path, true)) {
  49. w.Write (contents);
  50. }
  51. }
  52. public static void AppendAllText (string path, string contents, Encoding encoding)
  53. {
  54. using (TextWriter w = new StreamWriter (path, true, encoding)) {
  55. w.Write (contents);
  56. }
  57. }
  58. public static StreamWriter AppendText (string path)
  59. {
  60. return new StreamWriter (path, true);
  61. }
  62. public static void Copy (string sourceFileName, string destFileName)
  63. {
  64. Copy (sourceFileName, destFileName, false);
  65. }
  66. public static void Copy (string sourceFileName, string destFileName, bool overwrite)
  67. {
  68. MonoIOError error;
  69. if (sourceFileName == null)
  70. throw new ArgumentNullException ("sourceFileName");
  71. if (destFileName == null)
  72. throw new ArgumentNullException ("destFileName");
  73. if (sourceFileName.Length == 0)
  74. throw new ArgumentException ("An empty file name is not valid.", "sourceFileName");
  75. if (sourceFileName.Trim ().Length == 0 || sourceFileName.IndexOfAny (Path.InvalidPathChars) != -1)
  76. throw new ArgumentException ("The file name is not valid.");
  77. if (destFileName.Length == 0)
  78. throw new ArgumentException ("An empty file name is not valid.", "destFileName");
  79. if (destFileName.Trim ().Length == 0 || destFileName.IndexOfAny (Path.InvalidPathChars) != -1)
  80. throw new ArgumentException ("The file name is not valid.");
  81. SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
  82. if (!MonoIO.Exists (sourceFileName, out error))
  83. throw new FileNotFoundException (Locale.GetText ("{0} does not exist", sourceFileName), sourceFileName);
  84. if ((GetAttributes (sourceFileName) & FileAttributes.Directory) == FileAttributes.Directory)
  85. throw new ArgumentException (Locale.GetText ("{0} is a directory", sourceFileName));
  86. if (MonoIO.Exists (destFileName, out error)) {
  87. if ((GetAttributes (destFileName) & FileAttributes.Directory) == FileAttributes.Directory)
  88. throw new ArgumentException (Locale.GetText ("{0} is a directory", destFileName));
  89. if (!overwrite)
  90. throw new IOException (Locale.GetText ("{0} already exists", destFileName));
  91. }
  92. string DirName = Path.GetDirectoryName (destFileName);
  93. if (DirName != String.Empty && !Directory.Exists (DirName))
  94. throw new DirectoryNotFoundException (Locale.GetText ("Destination directory not found: {0}",DirName));
  95. if (!MonoIO.CopyFile (sourceFileName, destFileName, overwrite, out error)) {
  96. string p = Locale.GetText ("{0}\" or \"{1}", sourceFileName, destFileName);
  97. throw MonoIO.GetException (p, error);
  98. }
  99. }
  100. internal static String InternalCopy (String sourceFileName, String destFileName, bool overwrite, bool checkHost)
  101. {
  102. String fullSourceFileName = Path.GetFullPathInternal(sourceFileName);
  103. String fullDestFileName = Path.GetFullPathInternal(destFileName);
  104. MonoIOError error;
  105. if (!MonoIO.CopyFile (fullSourceFileName, fullDestFileName, overwrite, out error)) {
  106. string p = Locale.GetText ("{0}\" or \"{1}", sourceFileName, destFileName);
  107. throw MonoIO.GetException (p, error);
  108. }
  109. return fullDestFileName;
  110. }
  111. public static FileStream Create (string path)
  112. {
  113. return Create (path, 8192);
  114. }
  115. public static FileStream Create (string path, int bufferSize)
  116. {
  117. return new FileStream (path, FileMode.Create, FileAccess.ReadWrite,
  118. FileShare.None, bufferSize);
  119. }
  120. [MonoLimitation ("FileOptions are ignored")]
  121. public static FileStream Create (string path, int bufferSize,
  122. FileOptions options)
  123. {
  124. return new FileStream (path, FileMode.Create, FileAccess.ReadWrite,
  125. FileShare.None, bufferSize, options);
  126. }
  127. [MonoLimitation ("FileOptions and FileSecurity are ignored")]
  128. public static FileStream Create (string path, int bufferSize,
  129. FileOptions options,
  130. FileSecurity fileSecurity)
  131. {
  132. return new FileStream (path, FileMode.Create, FileAccess.ReadWrite,
  133. FileShare.None, bufferSize, options);
  134. }
  135. public static StreamWriter CreateText (string path)
  136. {
  137. return new StreamWriter (path, false);
  138. }
  139. public static void Delete (string path)
  140. {
  141. Path.Validate (path);
  142. if (Directory.Exists (path))
  143. throw new UnauthorizedAccessException(Locale.GetText ("{0} is a directory", path));
  144. string DirName = Path.GetDirectoryName(path);
  145. if (DirName != String.Empty && !Directory.Exists (DirName))
  146. throw new DirectoryNotFoundException (Locale.GetText ("Could not find a part of the path \"{0}\".", path));
  147. SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
  148. MonoIOError error;
  149. if (!MonoIO.DeleteFile (path, out error)){
  150. if (error != MonoIOError.ERROR_FILE_NOT_FOUND)
  151. throw MonoIO.GetException (path, error);
  152. }
  153. }
  154. public static bool Exists (string path)
  155. {
  156. // For security reasons no exceptions are
  157. // thrown, only false is returned if there is
  158. // any problem with the path or permissions.
  159. // Minimizes what information can be
  160. // discovered by using this method.
  161. if (String.IsNullOrWhiteSpace (path) || path.IndexOfAny(Path.InvalidPathChars) >= 0)
  162. return false;
  163. // on Moonlight this does not throw but returns false
  164. if (!SecurityManager.CheckElevatedPermissions ())
  165. return false;
  166. MonoIOError error;
  167. return MonoIO.ExistsFile (path, out error);
  168. }
  169. public static FileSecurity GetAccessControl (string path)
  170. {
  171. // AccessControlSections.Audit requires special permissions.
  172. return GetAccessControl (path,
  173. AccessControlSections.Owner |
  174. AccessControlSections.Group |
  175. AccessControlSections.Access);
  176. }
  177. public static FileSecurity GetAccessControl (string path, AccessControlSections includeSections)
  178. {
  179. return new FileSecurity (path, includeSections);
  180. }
  181. public static FileAttributes GetAttributes (string path)
  182. {
  183. Path.Validate (path);
  184. SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
  185. MonoIOError error;
  186. FileAttributes attrs;
  187. attrs = MonoIO.GetFileAttributes (path, out error);
  188. if (error != MonoIOError.ERROR_SUCCESS)
  189. throw MonoIO.GetException (path, error);
  190. return attrs;
  191. }
  192. public static DateTime GetCreationTime (string path)
  193. {
  194. MonoIOStat stat;
  195. MonoIOError error;
  196. Path.Validate (path);
  197. SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
  198. if (!MonoIO.GetFileStat (path, out stat, out error)) {
  199. if (error == MonoIOError.ERROR_PATH_NOT_FOUND || error == MonoIOError.ERROR_FILE_NOT_FOUND)
  200. return DefaultLocalFileTime;
  201. else
  202. throw new IOException (path);
  203. }
  204. return DateTime.FromFileTime (stat.CreationTime);
  205. }
  206. public static DateTime GetCreationTimeUtc (string path)
  207. {
  208. return GetCreationTime (path).ToUniversalTime ();
  209. }
  210. public static DateTime GetLastAccessTime (string path)
  211. {
  212. MonoIOStat stat;
  213. MonoIOError error;
  214. Path.Validate (path);
  215. SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
  216. if (!MonoIO.GetFileStat (path, out stat, out error)) {
  217. if (error == MonoIOError.ERROR_PATH_NOT_FOUND || error == MonoIOError.ERROR_FILE_NOT_FOUND)
  218. return DefaultLocalFileTime;
  219. else
  220. throw new IOException (path);
  221. }
  222. return DateTime.FromFileTime (stat.LastAccessTime);
  223. }
  224. public static DateTime GetLastAccessTimeUtc (string path)
  225. {
  226. return GetLastAccessTime (path).ToUniversalTime ();
  227. }
  228. public static DateTime GetLastWriteTime (string path)
  229. {
  230. MonoIOStat stat;
  231. MonoIOError error;
  232. Path.Validate (path);
  233. 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;
  237. else
  238. throw new IOException (path);
  239. }
  240. return DateTime.FromFileTime (stat.LastWriteTime);
  241. }
  242. public static DateTime GetLastWriteTimeUtc (string path)
  243. {
  244. return GetLastWriteTime (path).ToUniversalTime ();
  245. }
  246. public static void Move (string sourceFileName, string destFileName)
  247. {
  248. if (sourceFileName == null)
  249. throw new ArgumentNullException ("sourceFileName");
  250. if (destFileName == null)
  251. throw new ArgumentNullException ("destFileName");
  252. if (sourceFileName.Length == 0)
  253. throw new ArgumentException ("An empty file name is not valid.", "sourceFileName");
  254. if (sourceFileName.Trim ().Length == 0 || sourceFileName.IndexOfAny (Path.InvalidPathChars) != -1)
  255. throw new ArgumentException ("The file name is not valid.");
  256. if (destFileName.Length == 0)
  257. throw new ArgumentException ("An empty file name is not valid.", "destFileName");
  258. if (destFileName.Trim ().Length == 0 || destFileName.IndexOfAny (Path.InvalidPathChars) != -1)
  259. throw new ArgumentException ("The file name is not valid.");
  260. SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
  261. MonoIOError error;
  262. if (!MonoIO.Exists (sourceFileName, out error))
  263. throw new FileNotFoundException (Locale.GetText ("{0} does not exist", sourceFileName), sourceFileName);
  264. // Don't check for this error here to allow the runtime
  265. // to check if sourceFileName and destFileName are equal.
  266. // Comparing sourceFileName and destFileName is not enough.
  267. //if (MonoIO.Exists (destFileName, out error))
  268. // throw new IOException (Locale.GetText ("{0} already exists", destFileName));
  269. string DirName;
  270. DirName = Path.GetDirectoryName (destFileName);
  271. if (DirName != String.Empty && !Directory.Exists (DirName))
  272. throw new DirectoryNotFoundException (Locale.GetText ("Could not find a part of the path."));
  273. if (!MonoIO.MoveFile (sourceFileName, destFileName, out error)) {
  274. if (error == MonoIOError.ERROR_ALREADY_EXISTS)
  275. throw MonoIO.GetException (error);
  276. else if (error == MonoIOError.ERROR_SHARING_VIOLATION)
  277. throw MonoIO.GetException (sourceFileName, error);
  278. throw MonoIO.GetException (error);
  279. }
  280. }
  281. public static FileStream Open (string path, FileMode mode)
  282. {
  283. return new FileStream (path, mode, mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite, FileShare.None);
  284. }
  285. public static FileStream Open (string path, FileMode mode, FileAccess access)
  286. {
  287. return new FileStream (path, mode, access, FileShare.None);
  288. }
  289. public static FileStream Open (string path, FileMode mode, FileAccess access,
  290. FileShare share)
  291. {
  292. return new FileStream (path, mode, access, share);
  293. }
  294. public static FileStream OpenRead (string path)
  295. {
  296. return new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.Read);
  297. }
  298. public static StreamReader OpenText (string path)
  299. {
  300. return new StreamReader (path);
  301. }
  302. public static FileStream OpenWrite (string path)
  303. {
  304. return new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
  305. }
  306. public static void Replace (string sourceFileName,
  307. string destinationFileName,
  308. string destinationBackupFileName)
  309. {
  310. Replace (sourceFileName, destinationFileName, destinationBackupFileName, false);
  311. }
  312. public static void Replace (string sourceFileName,
  313. string destinationFileName,
  314. string destinationBackupFileName,
  315. bool ignoreMetadataErrors)
  316. {
  317. MonoIOError error;
  318. if (sourceFileName == null)
  319. throw new ArgumentNullException ("sourceFileName");
  320. if (destinationFileName == null)
  321. throw new ArgumentNullException ("destinationFileName");
  322. if (sourceFileName.Trim ().Length == 0 || sourceFileName.IndexOfAny (Path.InvalidPathChars) != -1)
  323. throw new ArgumentException ("sourceFileName");
  324. if (destinationFileName.Trim ().Length == 0 || destinationFileName.IndexOfAny (Path.InvalidPathChars) != -1)
  325. throw new ArgumentException ("destinationFileName");
  326. string fullSource = Path.GetFullPath (sourceFileName);
  327. string fullDest = Path.GetFullPath (destinationFileName);
  328. if (MonoIO.ExistsDirectory (fullSource, out error))
  329. throw new IOException (Locale.GetText ("{0} is a directory", sourceFileName));
  330. if (MonoIO.ExistsDirectory (fullDest, out error))
  331. throw new IOException (Locale.GetText ("{0} is a directory", destinationFileName));
  332. if (!Exists (fullSource))
  333. throw new FileNotFoundException (Locale.GetText ("{0} does not exist", sourceFileName),
  334. sourceFileName);
  335. if (!Exists (fullDest))
  336. throw new FileNotFoundException (Locale.GetText ("{0} does not exist", destinationFileName),
  337. destinationFileName);
  338. if (fullSource == fullDest)
  339. throw new IOException (Locale.GetText ("Source and destination arguments are the same file."));
  340. string fullBackup = null;
  341. if (destinationBackupFileName != null) {
  342. if (destinationBackupFileName.Trim ().Length == 0 ||
  343. destinationBackupFileName.IndexOfAny (Path.InvalidPathChars) != -1)
  344. throw new ArgumentException ("destinationBackupFileName");
  345. fullBackup = Path.GetFullPath (destinationBackupFileName);
  346. if (MonoIO.ExistsDirectory (fullBackup, out error))
  347. throw new IOException (Locale.GetText ("{0} is a directory", destinationBackupFileName));
  348. if (fullSource == fullBackup)
  349. throw new IOException (Locale.GetText ("Source and backup arguments are the same file."));
  350. if (fullDest == fullBackup)
  351. throw new IOException (Locale.GetText (
  352. "Destination and backup arguments are the same file."));
  353. }
  354. var attrs = GetAttributes (fullDest);
  355. // TODO: Should be done in wapi, win32 api handles this already
  356. if ((attrs & FileAttributes.ReadOnly) != 0)
  357. throw MonoIO.GetException (MonoIOError.ERROR_ACCESS_DENIED);
  358. if (!MonoIO.ReplaceFile (fullSource, fullDest, fullBackup,
  359. ignoreMetadataErrors, out error)) {
  360. throw MonoIO.GetException (error);
  361. }
  362. }
  363. public static void SetAccessControl (string path,
  364. FileSecurity fileSecurity)
  365. {
  366. if (null == fileSecurity)
  367. throw new ArgumentNullException ("fileSecurity");
  368. fileSecurity.PersistModifications (path);
  369. }
  370. public static void SetAttributes (string path,
  371. FileAttributes fileAttributes)
  372. {
  373. MonoIOError error;
  374. Path.Validate (path);
  375. if (!MonoIO.SetFileAttributes (path, fileAttributes, out error))
  376. throw MonoIO.GetException (path, error);
  377. }
  378. public static void SetCreationTime (string path, DateTime creationTime)
  379. {
  380. MonoIOError error;
  381. Path.Validate (path);
  382. if (!MonoIO.Exists (path, out error))
  383. throw MonoIO.GetException (path, error);
  384. if (!MonoIO.SetCreationTime (path, creationTime, out error))
  385. throw MonoIO.GetException (path, error);
  386. }
  387. public static void SetCreationTimeUtc (string path, DateTime creationTimeUtc)
  388. {
  389. SetCreationTime (path, creationTimeUtc.ToLocalTime ());
  390. }
  391. public static void SetLastAccessTime (string path, DateTime lastAccessTime)
  392. {
  393. MonoIOError error;
  394. Path.Validate (path);
  395. if (!MonoIO.Exists (path, out error))
  396. throw MonoIO.GetException (path, error);
  397. if (!MonoIO.SetLastAccessTime (path, lastAccessTime, out error))
  398. throw MonoIO.GetException (path, error);
  399. }
  400. public static void SetLastAccessTimeUtc (string path, DateTime lastAccessTimeUtc)
  401. {
  402. SetLastAccessTime (path, lastAccessTimeUtc.ToLocalTime ());
  403. }
  404. public static void SetLastWriteTime (string path,
  405. DateTime lastWriteTime)
  406. {
  407. MonoIOError error;
  408. Path.Validate (path);
  409. if (!MonoIO.Exists (path, out error))
  410. throw MonoIO.GetException (path, error);
  411. if (!MonoIO.SetLastWriteTime (path, lastWriteTime, out error))
  412. throw MonoIO.GetException (path, error);
  413. }
  414. public static void SetLastWriteTimeUtc (string path,
  415. DateTime lastWriteTimeUtc)
  416. {
  417. SetLastWriteTime (path, lastWriteTimeUtc.ToLocalTime ());
  418. }
  419. //
  420. // The documentation for this method is most likely wrong, it
  421. // talks about doing a "binary read", but the remarks say
  422. // that this "detects the encoding".
  423. //
  424. // This can not detect and do anything useful with the encoding
  425. // since the result is a byte [] not a char [].
  426. //
  427. public static byte [] ReadAllBytes (string path)
  428. {
  429. using (FileStream s = OpenRead (path)) {
  430. long size = s.Length;
  431. // limited to 2GB according to http://msdn.microsoft.com/en-us/library/system.io.file.readallbytes.aspx
  432. if (size > Int32.MaxValue)
  433. throw new IOException ("Reading more than 2GB with this call is not supported");
  434. int pos = 0;
  435. int count = (int) size;
  436. byte [] result = new byte [size];
  437. while (count > 0) {
  438. int n = s.Read (result, pos, count);
  439. if (n == 0)
  440. throw new IOException ("Unexpected end of stream");
  441. pos += n;
  442. count -= n;
  443. }
  444. return result;
  445. }
  446. }
  447. public static string [] ReadAllLines (string path)
  448. {
  449. using (StreamReader reader = File.OpenText (path)) {
  450. return ReadAllLines (reader);
  451. }
  452. }
  453. public static string [] ReadAllLines (string path, Encoding encoding)
  454. {
  455. using (StreamReader reader = new StreamReader (path, encoding)) {
  456. return ReadAllLines (reader);
  457. }
  458. }
  459. static string [] ReadAllLines (StreamReader reader)
  460. {
  461. List<string> list = new List<string> ();
  462. while (!reader.EndOfStream)
  463. list.Add (reader.ReadLine ());
  464. return list.ToArray ();
  465. }
  466. public static string ReadAllText (string path)
  467. {
  468. using (StreamReader sr = new StreamReader (path)) {
  469. return sr.ReadToEnd ();
  470. }
  471. }
  472. public static string ReadAllText (string path, Encoding encoding)
  473. {
  474. using (StreamReader sr = new StreamReader (path, encoding)) {
  475. return sr.ReadToEnd ();
  476. }
  477. }
  478. public static void WriteAllBytes (string path, byte [] bytes)
  479. {
  480. using (Stream stream = File.Create (path)) {
  481. stream.Write (bytes, 0, bytes.Length);
  482. }
  483. }
  484. public static void WriteAllLines (string path, string [] contents)
  485. {
  486. using (StreamWriter writer = new StreamWriter (path)) {
  487. WriteAllLines (writer, contents);
  488. }
  489. }
  490. public static void WriteAllLines (string path, string [] contents, Encoding encoding)
  491. {
  492. using (StreamWriter writer = new StreamWriter (path, false, encoding)) {
  493. WriteAllLines (writer, contents);
  494. }
  495. }
  496. static void WriteAllLines (StreamWriter writer, string [] contents)
  497. {
  498. foreach (string line in contents)
  499. writer.WriteLine (line);
  500. }
  501. public static void WriteAllText (string path, string contents)
  502. {
  503. WriteAllText (path, contents, EncodingHelper.UTF8Unmarked);
  504. }
  505. public static void WriteAllText (string path, string contents, Encoding encoding)
  506. {
  507. using (StreamWriter sw = new StreamWriter (path, false, encoding)) {
  508. sw.Write (contents);
  509. }
  510. }
  511. static DateTime? defaultLocalFileTime;
  512. static DateTime DefaultLocalFileTime {
  513. get {
  514. if (defaultLocalFileTime == null)
  515. defaultLocalFileTime = new DateTime (1601, 1, 1).ToLocalTime ();
  516. return defaultLocalFileTime.Value;
  517. }
  518. }
  519. [MonoLimitation ("File encryption isn't supported (even on NTFS).")]
  520. public static void Encrypt (string path)
  521. {
  522. // MS.NET support this only on NTFS file systems, i.e. it's a file-system (not a framework) feature.
  523. // otherwise it throws a NotSupportedException (or a PlatformNotSupportedException on older OS).
  524. // we throw the same (instead of a NotImplementedException) because most code should already be
  525. // handling this exception to work properly.
  526. throw new NotSupportedException (Locale.GetText ("File encryption isn't supported on any file system."));
  527. }
  528. [MonoLimitation ("File encryption isn't supported (even on NTFS).")]
  529. public static void Decrypt (string path)
  530. {
  531. // MS.NET support this only on NTFS file systems, i.e. it's a file-system (not a framework) feature.
  532. // otherwise it throws a NotSupportedException (or a PlatformNotSupportedException on older OS).
  533. // we throw the same (instead of a NotImplementedException) because most code should already be
  534. // handling this exception to work properly.
  535. throw new NotSupportedException (Locale.GetText ("File encryption isn't supported on any file system."));
  536. }
  537. public static IEnumerable<string> ReadLines (string path)
  538. {
  539. return ReadLines (File.OpenText (path));
  540. }
  541. public static IEnumerable<string> ReadLines (string path, Encoding encoding)
  542. {
  543. return ReadLines (new StreamReader (path, encoding));
  544. }
  545. // refactored in order to avoid compiler-generated names for Moonlight tools
  546. static IEnumerable<string> ReadLines (StreamReader reader)
  547. {
  548. using (reader) {
  549. string s;
  550. while ((s = reader.ReadLine ()) != null) {
  551. yield return s;
  552. }
  553. }
  554. }
  555. public static void AppendAllLines (string path, IEnumerable<string> contents)
  556. {
  557. Path.Validate (path);
  558. if (contents == null)
  559. return;
  560. using (TextWriter w = new StreamWriter (path, true)) {
  561. foreach (var line in contents)
  562. w.WriteLine (line);
  563. }
  564. }
  565. public static void AppendAllLines (string path, IEnumerable<string> contents, Encoding encoding)
  566. {
  567. Path.Validate (path);
  568. if (contents == null)
  569. return;
  570. using (TextWriter w = new StreamWriter (path, true, encoding)) {
  571. foreach (var line in contents)
  572. w.WriteLine (line);
  573. }
  574. }
  575. public static void WriteAllLines (string path, IEnumerable<string> contents)
  576. {
  577. Path.Validate (path);
  578. if (contents == null)
  579. return;
  580. using (TextWriter w = new StreamWriter (path, false)) {
  581. foreach (var line in contents)
  582. w.WriteLine (line);
  583. }
  584. }
  585. public static void WriteAllLines (string path, IEnumerable<string> contents, Encoding encoding)
  586. {
  587. Path.Validate (path);
  588. if (contents == null)
  589. return;
  590. using (TextWriter w = new StreamWriter (path, false, encoding)) {
  591. foreach (var line in contents)
  592. w.WriteLine (line);
  593. }
  594. }
  595. internal static int FillAttributeInfo (String path, ref MonoIOStat data, bool tryagain, bool returnErrorOnNotFound)
  596. {
  597. if (tryagain)
  598. throw new NotImplementedException ();
  599. MonoIOError error;
  600. MonoIO.GetFileStat (path, out data, out error);
  601. if (!returnErrorOnNotFound && (error == MonoIOError.ERROR_FILE_NOT_FOUND || error == MonoIOError.ERROR_PATH_NOT_FOUND || error == MonoIOError.ERROR_NOT_READY)) {
  602. data = default (MonoIOStat);
  603. data.fileAttributes = (FileAttributes) (-1);
  604. return 0;
  605. }
  606. return (int) error;
  607. }
  608. #region Copied from corefx
  609. internal static DateTimeOffset GetUtcDateTimeOffset(DateTime dateTime)
  610. {
  611. // File and Directory UTC APIs treat a DateTimeKind.Unspecified as UTC whereas
  612. // ToUniversalTime treats this as local.
  613. if (dateTime.Kind == DateTimeKind.Unspecified)
  614. {
  615. return DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
  616. }
  617. return dateTime.ToUniversalTime();
  618. }
  619. #endregion
  620. }
  621. }