File.cs 24 KB

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