File.cs 23 KB

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