FileSupportNonStatic.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.IO;
  7. using System.Text.RegularExpressions;
  8. using System.Threading;
  9. using System.Xml;
  10. namespace Wayne.Lib.IO
  11. {
  12. /// <summary>
  13. /// Support class for files.
  14. /// </summary>
  15. public class FileSupportNonStatic : IFileSupport
  16. {
  17. #region Properties
  18. /// <summary>
  19. /// Default encoding for reading and writing text files.
  20. /// </summary>
  21. public static readonly System.Text.Encoding DefaultEncoding = System.Text.Encoding.UTF8;
  22. /// <summary>
  23. /// The Paths implementation to be used.
  24. /// </summary>
  25. public IPaths Paths { get; private set; }
  26. #endregion
  27. /// <summary>
  28. /// Constructor. uses default paths implementation.
  29. /// </summary>
  30. public FileSupportNonStatic()
  31. {
  32. Paths = new PathsImplementation(this.UnresolvedDirectoryPathExists(@"c:\"));
  33. }
  34. /// <summary>
  35. /// Constructor.
  36. /// </summary>
  37. /// <param name="paths"></param>
  38. public FileSupportNonStatic(IPaths paths)
  39. {
  40. Paths = paths;
  41. }
  42. #region Open
  43. /// <summary>
  44. /// Opens a file.
  45. /// </summary>
  46. /// <param name="fileName"></param>
  47. /// <param name="fileMode"></param>
  48. /// <param name="fileAccess"></param>
  49. /// <param name="fileShare"></param>
  50. /// <param name="retries"></param>
  51. /// <param name="delayBetweenRetries"></param>
  52. /// <returns></returns>
  53. [System.Diagnostics.DebuggerStepThrough]
  54. public virtual Stream Open(string fileName, FileMode fileMode, FileAccess fileAccess, FileShare fileShare, int retries, int delayBetweenRetries)
  55. {
  56. if (retries < 0)
  57. throw new ArgumentException("Number of retries must be positive non-zero", "retries");
  58. if (delayBetweenRetries < 0)
  59. throw new ArgumentException("Delay between retries must be equal to or greater than zero.");
  60. fileName = Paths.Parse(fileName);
  61. int retriesLeft = retries;
  62. do
  63. {
  64. try
  65. {
  66. return FileOpen(fileName, fileMode, fileAccess, fileShare);
  67. }
  68. catch (IOException)
  69. {
  70. retriesLeft--;
  71. if (retriesLeft == 0)
  72. throw;
  73. ThreadSleep(delayBetweenRetries);
  74. }
  75. catch (UnauthorizedAccessException)
  76. {
  77. retriesLeft--;
  78. if (retriesLeft == 0)
  79. throw;
  80. ThreadSleep(delayBetweenRetries);
  81. }
  82. }
  83. while (true); //Exit either by returning, or by throwing the exception that occured.
  84. }
  85. /// <summary>
  86. /// Opens a file, using standard values for retries (100) and delayBetweenRetries(100)
  87. /// </summary>
  88. /// <param name="fileName"></param>
  89. /// <param name="fileMode"></param>
  90. /// <param name="fileAccess"></param>
  91. /// <param name="fileShare"></param>
  92. /// <returns></returns>
  93. public Stream Open(string fileName, FileMode fileMode, FileAccess fileAccess, FileShare fileShare)
  94. {
  95. return Open(fileName, fileMode, fileAccess, fileShare, 100, 100);
  96. }
  97. #endregion
  98. #region Move
  99. /// <summary>
  100. /// Moves a file.
  101. /// </summary>
  102. /// <param name="sourceFileName"></param>
  103. /// <param name="destinationFileName"></param>
  104. /// <param name="retries"></param>
  105. /// <param name="delayBetweenRetries"></param>
  106. [System.Diagnostics.DebuggerStepThrough]
  107. public void Move(string sourceFileName, string destinationFileName, int retries, int delayBetweenRetries)
  108. {
  109. if (retries <= 0)
  110. throw new ArgumentException("Number of retries must be positive non-zero", "retries");
  111. if (delayBetweenRetries < 0)
  112. throw new ArgumentException("Delay between retries must be equal to or greater than zero.");
  113. sourceFileName = Paths.Parse(sourceFileName);
  114. destinationFileName = Paths.Parse(destinationFileName);
  115. int retriesLeft = retries;
  116. do
  117. {
  118. try
  119. {
  120. if (FileExists(destinationFileName))
  121. FileDelete(destinationFileName);
  122. FileMove(sourceFileName, destinationFileName);
  123. return;
  124. }
  125. catch (IOException)
  126. {
  127. if (!FileExists(sourceFileName)) //If the source file does not even exist, then it is not worth looping.
  128. throw;
  129. retriesLeft--;
  130. if (retriesLeft == 0)
  131. throw;
  132. ThreadSleep(delayBetweenRetries);
  133. }
  134. catch (UnauthorizedAccessException)
  135. {
  136. if (!FileExists(sourceFileName)) //If the source file does not even exist, then it is not worth looping.
  137. throw;
  138. retriesLeft--;
  139. if (retriesLeft == 0)
  140. throw;
  141. ThreadSleep(delayBetweenRetries);
  142. }
  143. }
  144. while (true); //Exit either by returning, or by throwing the exception that occured.
  145. }
  146. /// <summary>
  147. /// Moves a file, using standard values for retries (100) and delayBetweenRetries(100)
  148. /// </summary>
  149. /// <param name="sourceFileName"></param>
  150. /// <param name="destinationFileName"></param>
  151. [System.Diagnostics.DebuggerStepThrough]
  152. public void Move(string sourceFileName, string destinationFileName)
  153. {
  154. Move(sourceFileName, destinationFileName, 100, 100);
  155. }
  156. /// <summary>
  157. /// Moves an entire directory from one location to another
  158. /// </summary>
  159. /// <param name="sourceDirName"></param>
  160. /// <param name="destDirName"></param>
  161. public void MoveDirectory(string sourceDirName, string destDirName)
  162. {
  163. MoveDirectory(sourceDirName, destDirName, 100, 100);
  164. }
  165. /// <summary>
  166. /// Moves an entire directory from one location to another
  167. /// </summary>
  168. /// <param name="sourceDirName"></param>
  169. /// <param name="destDirName"></param>
  170. /// <param name="retries"></param>
  171. /// <param name="delayBetweenRetries"></param>
  172. public void MoveDirectory(string sourceDirName, string destDirName, int retries, int delayBetweenRetries)
  173. {
  174. if (retries <= 0)
  175. throw new ArgumentException("Number of retries must be positive non-zero", "retries");
  176. if (delayBetweenRetries < 0)
  177. throw new ArgumentException("Delay between retries must be equal to or greater than zero.");
  178. sourceDirName = Paths.Parse(sourceDirName);
  179. destDirName = Paths.Parse(destDirName);
  180. int retriesLeft = retries;
  181. do
  182. {
  183. try
  184. {
  185. DirectoryMove(sourceDirName, destDirName);
  186. return;
  187. }
  188. catch (IOException)
  189. {
  190. if (DirectoryExists(destDirName) || !DirectoryExists(sourceDirName)) //If the dest dir already exist -or- the source dir does not even exist, then it is not worth looping.
  191. throw;
  192. retriesLeft--;
  193. if (retriesLeft == 0)
  194. throw;
  195. ThreadSleep(delayBetweenRetries);
  196. }
  197. catch (UnauthorizedAccessException)
  198. {
  199. if (DirectoryExists(destDirName) || !DirectoryExists(sourceDirName)) //If the dest dir already exist -or- the source dir does not even exist, then it is not worth looping.
  200. throw;
  201. retriesLeft--;
  202. if (retriesLeft == 0)
  203. throw;
  204. ThreadSleep(delayBetweenRetries);
  205. }
  206. }
  207. while (true); //Exit either by returning, or by throwing the exception that occured.
  208. }
  209. #endregion
  210. #region Delete
  211. /// <summary>
  212. /// Deletes a file
  213. /// </summary>
  214. /// <param name="fileName"></param>
  215. /// <param name="retries"></param>
  216. /// <param name="delayBetweenRetries"></param>
  217. [System.Diagnostics.DebuggerStepThrough]
  218. public void Delete(string fileName, int retries, int delayBetweenRetries)
  219. {
  220. if (retries <= 0)
  221. throw new ArgumentException("Number of retries must be positive non-zero", "retries");
  222. if (delayBetweenRetries < 0)
  223. throw new ArgumentException("Delay between retries must be equal to or greater than zero.");
  224. fileName = Paths.Parse(fileName);
  225. int retriesLeft = retries;
  226. do
  227. {
  228. try
  229. {
  230. if (FileExists(fileName))
  231. FileDelete(fileName);
  232. return;
  233. }
  234. catch (IOException)
  235. {
  236. if (!FileExists(fileName)) //If the source file does not even exist, then it is not worth looping.
  237. throw;
  238. retriesLeft--;
  239. if (retriesLeft == 0)
  240. throw;
  241. ThreadSleep(delayBetweenRetries);
  242. }
  243. catch (UnauthorizedAccessException)
  244. {
  245. if (!FileExists(fileName)) //If the source file does not even exist, then it is not worth looping.
  246. throw;
  247. retriesLeft--;
  248. if (retriesLeft == 0)
  249. throw;
  250. ThreadSleep(delayBetweenRetries);
  251. }
  252. }
  253. while (true); //Exit either by returning, or by throwing the exception that occured.
  254. }
  255. /// <summary>
  256. /// Deletes a file, using standard values for retries (100) and delayBetweenRetries(100)
  257. /// </summary>
  258. /// <param name="fileName"></param>
  259. [System.Diagnostics.DebuggerStepThrough]
  260. public void Delete(string fileName)
  261. {
  262. Delete(fileName, 100, 100);
  263. }
  264. #endregion
  265. #region SecureDelete
  266. private ISecureDeleteSupport secureDeleteSupport;
  267. private readonly object secureDeleteSupportSyncObj = new object();
  268. /// <summary>
  269. /// Get- and set property for the SecureDelete support object. Needed to create backend to the secure delete function.
  270. /// </summary>
  271. public ISecureDeleteSupport SecureDeleteSupport
  272. {
  273. get
  274. {
  275. lock (secureDeleteSupportSyncObj)
  276. {
  277. return secureDeleteSupport;
  278. }
  279. }
  280. set
  281. {
  282. lock (secureDeleteSupportSyncObj)
  283. {
  284. secureDeleteSupport = value;
  285. }
  286. }
  287. }
  288. /// <summary>
  289. /// Deletes a file securely.
  290. /// </summary>
  291. /// <param name="fileName"></param>
  292. /// <param name="sDeleteOK"></param>
  293. /// <param name="retries"></param>
  294. /// <param name="delayBetweenRetries"></param>
  295. public void SecureDelete(string fileName, out bool sDeleteOK, int retries, int delayBetweenRetries)
  296. {
  297. lock (secureDeleteSupportSyncObj)
  298. {
  299. if (secureDeleteSupport == null)
  300. throw new NullReferenceException("The SecureDeleteSupport property is not assigned!");
  301. SecureDeleteSupport.SecureDelete(fileName, out sDeleteOK, retries, delayBetweenRetries);
  302. }
  303. }
  304. /// <summary>
  305. /// Deletes a file securely.
  306. /// </summary>
  307. /// <param name="fileName"></param>
  308. /// <param name="sDeleteOK"></param>
  309. public void SecureDelete(string fileName, out bool sDeleteOK)
  310. {
  311. SecureDelete(fileName, out sDeleteOK, 100, 100);
  312. }
  313. #endregion
  314. #region Copy
  315. /// <summary>
  316. /// Copy a file.
  317. /// </summary>
  318. /// <param name="sourceFileName"></param>
  319. /// <param name="destinationFileName"></param>
  320. /// <param name="overwrite"></param>
  321. public void Copy(string sourceFileName, string destinationFileName, bool overwrite)
  322. {
  323. Copy(sourceFileName, destinationFileName, overwrite, 100, 100);
  324. }
  325. /// <summary>
  326. /// Copies a file.
  327. /// </summary>
  328. /// <param name="sourceFileName"></param>
  329. /// <param name="destinationFileName"></param>
  330. /// <param name="overwrite"></param>
  331. /// <param name="retries"></param>
  332. /// <param name="delayBetweenRetries"></param>
  333. [System.Diagnostics.DebuggerStepThrough]
  334. public virtual void Copy(string sourceFileName, string destinationFileName, bool overwrite, int retries, int delayBetweenRetries)
  335. {
  336. if (retries <= 0)
  337. throw new ArgumentException("Number of retries must be positive non-zero", "retries");
  338. if (delayBetweenRetries < 0)
  339. throw new ArgumentException("Delay between retries must be equal to or greater than zero.");
  340. sourceFileName = Paths.Parse(sourceFileName);
  341. destinationFileName = Paths.Parse(destinationFileName);
  342. int retriesLeft = retries;
  343. do
  344. {
  345. try
  346. {
  347. if (FileExists(destinationFileName))
  348. FileDelete(destinationFileName);
  349. FileCopy(sourceFileName, destinationFileName, overwrite);
  350. return;
  351. }
  352. catch (IOException)
  353. {
  354. if (!FileExists(sourceFileName)) //If the source file does not even exist, then it is not worth looping.
  355. throw;
  356. retriesLeft--;
  357. if (retriesLeft == 0)
  358. throw;
  359. ThreadSleep(delayBetweenRetries);
  360. }
  361. catch (UnauthorizedAccessException)
  362. {
  363. if (!FileExists(sourceFileName)) //If the source file does not even exist, then it is not worth looping.
  364. throw;
  365. retriesLeft--;
  366. if (retriesLeft == 0)
  367. throw;
  368. ThreadSleep(delayBetweenRetries);
  369. }
  370. }
  371. while (true); //Exit either by returning, or by throwing the exception that occured.
  372. }
  373. #endregion
  374. #region LoadFromFile/SaveToFile
  375. /// <summary>
  376. /// Read the lines of a text file into a string.
  377. /// </summary>
  378. /// <param name="fileName">The path and file name.</param>
  379. public string LoadToString(string fileName)
  380. {
  381. return LoadToString(fileName, DefaultEncoding);
  382. }
  383. /// <summary>
  384. /// Read the lines of a text file into a string.
  385. /// </summary>
  386. /// <param name="fileName">The path and file name.</param>
  387. /// <param name="encoding">The encoding.</param>
  388. public virtual string LoadToString(string fileName, System.Text.Encoding encoding)
  389. {
  390. if (fileName == null)
  391. throw new ArgumentNullException("fileName");
  392. if (encoding == null)
  393. throw new ArgumentNullException("encoding");
  394. using (Stream stream = Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
  395. {
  396. using (StreamReader reader = new StreamReader(stream, encoding))
  397. {
  398. return reader.ReadToEnd();
  399. }
  400. }
  401. }
  402. /// <summary>
  403. /// Read the lines of a text file into an array of strings.
  404. /// </summary>
  405. /// <param name="fileName">The path and file name.</param>
  406. public string[] LoadToStringArray(string fileName)
  407. {
  408. return LoadToStringArray(fileName, DefaultEncoding);
  409. }
  410. /// <summary>
  411. /// Read the lines of a text file into an array of strings.
  412. /// </summary>
  413. /// <param name="fileName">The path and file name.</param>
  414. /// <param name="encoding">The encoding.</param>
  415. public string[] LoadToStringArray(string fileName, System.Text.Encoding encoding)
  416. {
  417. return Regex.Split(LoadToString(fileName, encoding), "\r\n");
  418. }
  419. /// <summary>
  420. /// Saves a text string to a file.
  421. /// </summary>
  422. /// <param name="fileName">The path and file name.</param>
  423. /// <param name="text">The text to save.</param>
  424. public void SaveToFile(string fileName, string text)
  425. {
  426. SaveToFile(fileName, text, DefaultEncoding);
  427. }
  428. /// <summary>
  429. /// Saves a text string to a file.
  430. /// </summary>
  431. /// <param name="fileName">The path and file name.</param>
  432. /// <param name="lines">The lines to save.</param>
  433. public void SaveToFile(string fileName, string[] lines)
  434. {
  435. SaveToFile(fileName, lines, DefaultEncoding);
  436. }
  437. /// <summary>
  438. /// Saves a text string to a file.
  439. /// </summary>
  440. /// <param name="fileName">The path and file name.</param>
  441. /// <param name="text">The text to save.</param>
  442. /// <param name="encoding">The encoding.</param>
  443. public void SaveToFile(string fileName, string text, System.Text.Encoding encoding)
  444. {
  445. if (fileName == null)
  446. throw new ArgumentNullException("fileName");
  447. if (text == null)
  448. throw new ArgumentNullException("text");
  449. if (encoding == null)
  450. throw new ArgumentNullException("encoding");
  451. using (Stream stream = Open(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
  452. {
  453. byte[] bytes = encoding.GetBytes(text);
  454. stream.Write(bytes, 0, bytes.Length);
  455. }
  456. }
  457. /// <summary>
  458. /// Saves a text string to a file.
  459. /// </summary>
  460. /// <param name="fileName">The path and file name.</param>
  461. /// <param name="lines">The lines to save.</param>
  462. /// <param name="encoding">The encoding.</param>
  463. public void SaveToFile(string fileName, string[] lines, System.Text.Encoding encoding)
  464. {
  465. SaveToFile(fileName, string.Join("\r\n", lines), encoding);
  466. }
  467. /// <summary>
  468. /// Loads the specified XML file into the XmlDocument.
  469. /// </summary>
  470. /// <param name="xmlDocument">The XmlDocument to load.</param>
  471. /// <param name="fileName">The path and file name.</param>
  472. public void LoadXml(XmlDocument xmlDocument, string fileName)
  473. {
  474. LoadXml(xmlDocument, fileName, DefaultEncoding);
  475. }
  476. /// <summary>
  477. /// Loads the specified XML file into the XmlDocument.
  478. /// </summary>
  479. /// <param name="xmlDocument">The XmlDocument to load.</param>
  480. /// <param name="fileName">The path and file name.</param>
  481. /// <param name="encoding">The encoding.</param>
  482. public void LoadXml(XmlDocument xmlDocument, string fileName, System.Text.Encoding encoding)
  483. {
  484. xmlDocument.LoadXml(LoadToString(fileName, encoding));
  485. }
  486. #endregion
  487. private IFileSupportExtension fileSupportExtension;
  488. private readonly object fileSupportExtensionSyncObj = new object();
  489. /// <summary>
  490. /// Gets or sets tha File support extension that can be different depending on the execution platform (WinCE or Win32)
  491. /// </summary>
  492. public IFileSupportExtension FileSupportExtension
  493. {
  494. get
  495. {
  496. lock (fileSupportExtensionSyncObj)
  497. {
  498. return fileSupportExtension;
  499. }
  500. }
  501. set
  502. {
  503. lock (fileSupportExtensionSyncObj)
  504. {
  505. fileSupportExtension = value;
  506. }
  507. }
  508. }
  509. /// <summary>
  510. /// Set creation time on a file.
  511. /// </summary>
  512. /// <param name="fileName"></param>
  513. public DateTime GetCreationTime(string fileName)
  514. {
  515. lock (fileSupportExtensionSyncObj)
  516. {
  517. if (fileSupportExtension == null)
  518. throw new NullReferenceException("The FileSupportExtension property is not assigned!");
  519. return fileSupportExtension.GetCreationTime(fileName);
  520. }
  521. }
  522. /// <summary>
  523. /// Set creation time on a file.
  524. /// </summary>
  525. /// <param name="fileName"></param>
  526. /// <param name="dateTime"></param>
  527. public void SetCreationTime(string fileName, DateTime dateTime)
  528. {
  529. lock (fileSupportExtensionSyncObj)
  530. {
  531. if (fileSupportExtension == null)
  532. throw new NullReferenceException("The FileSupportExtension property is not assigned!");
  533. fileSupportExtension.SetCreationTime(fileName, dateTime);
  534. }
  535. }
  536. /// <summary>
  537. /// Set last access time on a file.
  538. /// </summary>
  539. /// <param name="fileName"></param>
  540. public DateTime GetLastAccessTime(string fileName)
  541. {
  542. lock (fileSupportExtensionSyncObj)
  543. {
  544. if (fileSupportExtension == null)
  545. throw new NullReferenceException("The FileSupportExtension property is not assigned!");
  546. return fileSupportExtension.GetLastAccessTime(fileName);
  547. }
  548. }
  549. /// <summary>
  550. /// Set last access time on a file.
  551. /// </summary>
  552. /// <param name="fileName"></param>
  553. /// <param name="dateTime"></param>
  554. public void SetLastAccessTime(string fileName, DateTime dateTime)
  555. {
  556. lock (fileSupportExtensionSyncObj)
  557. {
  558. if (fileSupportExtension == null)
  559. throw new NullReferenceException("The FileSupportExtension property is not assigned!");
  560. fileSupportExtension.SetLastAccessTime(fileName, dateTime);
  561. }
  562. }
  563. /// <summary>
  564. /// Get last write time on the file.
  565. /// </summary>
  566. /// <param name="fileName"></param>
  567. public DateTime GetLastWriteTime(string fileName)
  568. {
  569. lock (fileSupportExtensionSyncObj)
  570. {
  571. if (fileSupportExtension == null)
  572. throw new NullReferenceException("The FileSupportExtension property is not assigned!");
  573. return fileSupportExtension.GetLastWriteTime(fileName);
  574. }
  575. }
  576. /// <summary>
  577. /// Set last write time on the file.
  578. /// </summary>
  579. /// <param name="fileName"></param>
  580. /// <param name="dateTime"></param>
  581. public void SetLastWriteTime(string fileName, DateTime dateTime)
  582. {
  583. lock (fileSupportExtensionSyncObj)
  584. {
  585. if (fileSupportExtension == null)
  586. throw new NullReferenceException("The FileSupportExtension property is not assigned!");
  587. fileSupportExtension.SetLastWriteTime(fileName, dateTime);
  588. }
  589. }
  590. /// <summary>
  591. /// Checks if the file exists
  592. /// </summary>
  593. /// <param name="fileName"></param>
  594. /// <returns></returns>
  595. [System.Diagnostics.DebuggerStepThrough]
  596. public virtual bool FileExists(string fileName)
  597. {
  598. return File.Exists(Paths.Parse(fileName));
  599. }
  600. /// <summary>
  601. /// Deletes the file.
  602. /// </summary>
  603. /// <param name="fileName"></param>
  604. [System.Diagnostics.DebuggerStepThrough]
  605. protected virtual void FileDelete(string fileName)
  606. {
  607. File.Delete(fileName);
  608. }
  609. /// <summary>
  610. /// Opens a file.
  611. /// </summary>
  612. /// <param name="fileName"></param>
  613. /// <param name="fileMode"></param>
  614. /// <param name="fileAccess"></param>
  615. /// <param name="fileShare"></param>
  616. /// <returns></returns>
  617. [System.Diagnostics.DebuggerStepThrough]
  618. protected virtual Stream FileOpen(string fileName, FileMode fileMode, FileAccess fileAccess, FileShare fileShare)
  619. {
  620. return File.Open(fileName, fileMode, fileAccess, fileShare);
  621. }
  622. /// <summary>
  623. /// Copies a file
  624. /// </summary>
  625. /// <param name="sourceFileName"></param>
  626. /// <param name="destinationFileName"></param>
  627. /// <param name="overwrite"></param>
  628. [System.Diagnostics.DebuggerStepThrough]
  629. protected virtual void FileCopy(string sourceFileName, string destinationFileName, bool overwrite)
  630. {
  631. File.Copy(sourceFileName, destinationFileName, overwrite);
  632. }
  633. /// <summary>
  634. /// Moves a file
  635. /// </summary>
  636. /// <param name="sourceFileName"></param>
  637. /// <param name="destinationFileName"></param>
  638. [System.Diagnostics.DebuggerStepThrough]
  639. protected virtual void FileMove(string sourceFileName, string destinationFileName)
  640. {
  641. File.Move(sourceFileName, destinationFileName);
  642. }
  643. /// <summary>
  644. /// Moves a directory
  645. /// </summary>
  646. /// <param name="sourceDirName"></param>
  647. /// <param name="destinationDirName"></param>
  648. [System.Diagnostics.DebuggerStepThrough]
  649. protected virtual void DirectoryMove(string sourceDirName, string destinationDirName)
  650. {
  651. Directory.Move(sourceDirName, destinationDirName);
  652. }
  653. /// <summary>
  654. /// Puts the thread in sleep mode.
  655. /// </summary>
  656. /// <param name="millisecondsTimeout"></param>
  657. [System.Diagnostics.DebuggerStepThrough]
  658. protected virtual void ThreadSleep(int millisecondsTimeout)
  659. {
  660. Thread.Sleep(millisecondsTimeout);
  661. }
  662. /// <summary>
  663. /// Copies the content of one directory into another.
  664. /// </summary>
  665. /// <param name="sourcePath"></param>
  666. /// <param name="destinationPath"></param>
  667. /// <param name="recurse"></param>
  668. public void CopyDirectory(string sourcePath, string destinationPath, bool recurse)
  669. {
  670. if (!DirectoryExists(sourcePath))
  671. throw new DirectoryNotFoundException(string.Format("Directory {0} does not exist", sourcePath));
  672. sourcePath = IO.Paths.Parse(sourcePath);
  673. destinationPath = IO.Paths.Parse(destinationPath);
  674. if (destinationPath[destinationPath.Length - 1] != Path.DirectorySeparatorChar)
  675. destinationPath += Path.DirectorySeparatorChar;
  676. if (sourcePath[sourcePath.Length - 1] != Path.DirectorySeparatorChar)
  677. sourcePath += Path.DirectorySeparatorChar;
  678. EnsureDirectoryExists(destinationPath);
  679. //Copy all the folders.
  680. string[] subDirectories = GetDirectories(sourcePath, true);
  681. foreach (var subDir in subDirectories)
  682. {
  683. string destinationFolder = SourceToDest(sourcePath, destinationPath, subDir);
  684. EnsureDirectoryExists(destinationFolder);
  685. }
  686. //Copy all the files.
  687. string[] files = GetFiles(sourcePath, "*.*", true);
  688. foreach (var file in files)
  689. {
  690. Copy(file, SourceToDest(sourcePath, destinationPath, file), true);
  691. }
  692. }
  693. private string SourceToDest(string sourcePath, string destinationPath, string sourceSubDir)
  694. {
  695. string replace = sourceSubDir.Replace(sourcePath, "");
  696. string result = Path.Combine(destinationPath, replace);
  697. return result;
  698. }
  699. /// <summary>
  700. /// Returns the names of files in the specified directory that match the specified search pattern.
  701. /// </summary>
  702. /// <param name="path">The directory to search.</param>
  703. /// <param name="searchPattern">The search string to match against the names of files in path. The parameter cannot end in two periods ("..") or contain two periods ("..") followed by System.IO.Path.DirectorySeparatorChar or System.IO.Path.AltDirectorySeparatorChar, nor can it contain any of the characters in System.IO.Path.InvalidPathChars.</param>
  704. /// <returns></returns>
  705. public string[] GetFiles(string path, string searchPattern)
  706. {
  707. return GetFiles(path, searchPattern, false);
  708. }
  709. /// <summary>
  710. /// Returns the names of files in the specified directory that match the specified search pattern.
  711. /// </summary>
  712. /// <param name="path">The directory to search.</param>
  713. /// <param name="searchPattern">The search string to match against the names of files in path. The parameter cannot end in two periods ("..") or contain two periods ("..") followed by System.IO.Path.DirectorySeparatorChar or System.IO.Path.AltDirectorySeparatorChar, nor can it contain any of the characters in System.IO.Path.InvalidPathChars.</param>
  714. /// <param name="recursive">Should the subdirectories be included in the search.</param>
  715. /// <returns></returns>
  716. public virtual string[] GetFiles(string path, string searchPattern, bool recursive)
  717. {
  718. List<string> files = new List<string>();
  719. files.AddRange(Directory.GetFiles(Paths.Parse(path), searchPattern));
  720. if (recursive)
  721. {
  722. foreach (string directory in GetDirectories(path))
  723. {
  724. files.AddRange(GetFiles(directory, searchPattern, true));
  725. }
  726. }
  727. return files.ToArray();
  728. }
  729. /// <summary>
  730. /// Returns the names of subdirectories in the specified directory that match the specified search pattern.
  731. /// </summary>
  732. /// <param name="path">The directory to search.</param>
  733. /// <returns></returns>
  734. public virtual string[] GetDirectories(string path)
  735. {
  736. return Directory.GetDirectories(Paths.Parse(path));
  737. }
  738. /// <summary>
  739. /// Returns the subdirectories of the path
  740. /// </summary>
  741. /// <param name="path"></param>
  742. /// <param name="recursive">True if the method should get all subdirectories recursively.</param>
  743. /// <returns></returns>
  744. public string[] GetDirectories(string path, bool recursive)
  745. {
  746. if (!recursive) return GetDirectories(path);
  747. var stack = new Stack<string>();
  748. stack.Push(path);
  749. var dirsFound = new List<string>();
  750. while (stack.Any())
  751. {
  752. GetDirectories(stack.Pop()).ForEach(dir =>
  753. {
  754. stack.Push(dir);
  755. dirsFound.Add(dir);
  756. });
  757. }
  758. return dirsFound.ToArray();
  759. }
  760. /// <summary>
  761. /// Checks if directory exists
  762. /// </summary>
  763. /// <param name="path"></param>
  764. /// <returns></returns>
  765. public virtual bool DirectoryExists(string path)
  766. {
  767. return Directory.Exists(Paths.Parse(path));
  768. }
  769. /// <summary>
  770. /// Checks if the unresolved directory exits.
  771. /// </summary>
  772. /// <param name="path"></param>
  773. /// <returns></returns>
  774. private bool UnresolvedDirectoryPathExists(string path)
  775. {
  776. return Directory.Exists(path);
  777. }
  778. /// <summary>
  779. /// Ensures the directory exists by trying to create it if it does not exist already.
  780. /// </summary>
  781. /// <param name="path"></param>
  782. /// <returns></returns>
  783. [System.Diagnostics.DebuggerStepThrough]
  784. public virtual bool EnsureDirectoryExists(string path)
  785. {
  786. path = Paths.Parse(path);
  787. try
  788. {
  789. if (!Directory.Exists(path))
  790. Directory.CreateDirectory(path);
  791. }
  792. catch { }
  793. return Directory.Exists(path);
  794. }
  795. /// <summary>
  796. /// OBSOLETE - Use EnsureDirectoryExists() instead.
  797. /// </summary>
  798. /// <param name="directoryName"></param>
  799. [System.Diagnostics.DebuggerStepThrough]
  800. [Obsolete("Use EnsureDirectoryExists() instead.")]
  801. public virtual void EnsureDirectoriesExists(string directoryName)
  802. {
  803. EnsureDirectoryExists(directoryName);
  804. }
  805. /// <summary>
  806. /// Removes a directory.
  807. /// </summary>
  808. /// <param name="path"></param>
  809. /// <param name="onlyIfEmpty"></param>
  810. /// <returns></returns>
  811. public virtual bool RemoveDirectory(string path, bool onlyIfEmpty)
  812. {
  813. if (!Directory.Exists(path))
  814. return true;
  815. if (!onlyIfEmpty)
  816. Directory.Delete(path, true);
  817. else if ((GetFiles(path, "*.*").Length == 0) && (GetDirectories(path).Length == 0))
  818. Directory.Delete(path);
  819. return !Directory.Exists(path);
  820. }
  821. /// <summary>
  822. /// Checks if the filename is valid.
  823. /// </summary>
  824. /// <param name="fileName"></param>
  825. /// <returns>True if the filename is valid otherwise false.</returns>
  826. public virtual bool IsValidFileName(string fileName)
  827. {
  828. return fileName != null && Regex.IsMatch(Paths.Parse(fileName), string.Format(@"^([^{0}]+[/\\])*[/\\]?[^{1}]+?$",
  829. Regex.Escape(new string(Path.GetInvalidPathChars())),
  830. Regex.Escape(new string(Path.GetInvalidPathChars()) + @":*?\/")));
  831. }
  832. /// <summary>
  833. /// Checks if the filepath is valid
  834. /// </summary>
  835. /// <param name="pathName"></param>
  836. /// <returns>True if the filepath is valid otherwise false.</returns>
  837. public virtual bool IsValidPathName(string pathName)
  838. {
  839. return pathName != null && Regex.IsMatch(Paths.Parse(pathName), string.Format(@"^[^{0}]*$",
  840. Regex.Escape(new string(Path.GetInvalidPathChars()))));
  841. }
  842. }
  843. }