SftpFile.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Security;
  5. using System.Globalization;
  6. namespace Renci.SshNet.Sftp
  7. {
  8. /// <summary>
  9. /// Represents SFTP file information
  10. /// </summary>
  11. public class SftpFile
  12. {
  13. private SftpSession _sftpSession;
  14. /// <summary>
  15. /// Gets the file attributes.
  16. /// </summary>
  17. public SftpFileAttributes Attributes { get; private set; }
  18. /// <summary>
  19. /// Initializes a new instance of the <see cref="SftpFile"/> class.
  20. /// </summary>
  21. /// <param name="sftpSession">The SFTP session.</param>
  22. /// <param name="fullName">Full path of the directory or file.</param>
  23. /// <param name="attributes">Attributes of the directory or file.</param>
  24. /// <exception cref="ArgumentNullException"><paramref name="sftpSession"/> or <paramref name="fullName"/> is null.</exception>
  25. internal SftpFile(SftpSession sftpSession, string fullName, SftpFileAttributes attributes)
  26. {
  27. if (attributes == null)
  28. throw new ArgumentNullException("attributes");
  29. if (fullName == null)
  30. throw new ArgumentNullException("fullName");
  31. this._sftpSession = sftpSession;
  32. this.Attributes = attributes;
  33. this.Name = fullName.Substring(fullName.LastIndexOf('/') + 1);
  34. this.FullName = fullName;
  35. }
  36. /// <summary>
  37. /// Gets the full path of the directory or file.
  38. /// </summary>
  39. public string FullName { get; private set; }
  40. /// <summary>
  41. /// For files, gets the name of the file. For directories, gets the name of the last directory in the hierarchy if a hierarchy exists.
  42. /// Otherwise, the Name property gets the name of the directory.
  43. /// </summary>
  44. public string Name { get; private set; }
  45. /// <summary>
  46. /// Gets or sets the time the current file or directory was last accessed.
  47. /// </summary>
  48. /// <value>
  49. /// The time that the current file or directory was last accessed.
  50. /// </value>
  51. public DateTime LastAccessTime
  52. {
  53. get
  54. {
  55. return this.Attributes.LastAccessTime;
  56. }
  57. set
  58. {
  59. this.Attributes.LastAccessTime = value;
  60. }
  61. }
  62. /// <summary>
  63. /// Gets or sets the time when the current file or directory was last written to.
  64. /// </summary>
  65. /// <value>
  66. /// The time the current file was last written.
  67. /// </value>
  68. public DateTime LastWriteTime
  69. {
  70. get
  71. {
  72. return this.Attributes.LastWriteTime;
  73. }
  74. set
  75. {
  76. this.Attributes.LastWriteTime = value;
  77. }
  78. }
  79. /// <summary>
  80. /// Gets or sets the time, in coordinated universal time (UTC), the current file or directory was last accessed.
  81. /// </summary>
  82. /// <value>
  83. /// The time that the current file or directory was last accessed.
  84. /// </value>
  85. public DateTime LastAccessTimeUtc
  86. {
  87. get
  88. {
  89. return this.Attributes.LastAccessTime.ToUniversalTime();
  90. }
  91. set
  92. {
  93. this.Attributes.LastAccessTime = value.ToLocalTime();
  94. }
  95. }
  96. /// <summary>
  97. /// Gets or sets the time, in coordinated universal time (UTC), when the current file or directory was last written to.
  98. /// </summary>
  99. /// <value>
  100. /// The time the current file was last written.
  101. /// </value>
  102. public DateTime LastWriteTimeUtc
  103. {
  104. get
  105. {
  106. return this.Attributes.LastWriteTime.ToUniversalTime();
  107. }
  108. set
  109. {
  110. this.Attributes.LastWriteTime = value.ToLocalTime();
  111. }
  112. }
  113. /// <summary>
  114. /// Gets or sets the size, in bytes, of the current file.
  115. /// </summary>
  116. /// <value>
  117. /// The size of the current file in bytes.
  118. /// </value>
  119. public long Length
  120. {
  121. get
  122. {
  123. return this.Attributes.Size;
  124. }
  125. }
  126. /// <summary>
  127. /// Gets or sets file user id.
  128. /// </summary>
  129. /// <value>
  130. /// File user id.
  131. /// </value>
  132. public int UserId
  133. {
  134. get
  135. {
  136. return this.Attributes.UserId;
  137. }
  138. set
  139. {
  140. this.Attributes.UserId = value;
  141. }
  142. }
  143. /// <summary>
  144. /// Gets or sets file group id.
  145. /// </summary>
  146. /// <value>
  147. /// File group id.
  148. /// </value>
  149. public int GroupId
  150. {
  151. get
  152. {
  153. return this.Attributes.GroupId;
  154. }
  155. set
  156. {
  157. this.Attributes.GroupId = value;
  158. }
  159. }
  160. /// <summary>
  161. /// Gets a value indicating whether file represents a socket.
  162. /// </summary>
  163. /// <value>
  164. /// <c>true</c> if file represents a socket; otherwise, <c>false</c>.
  165. /// </value>
  166. public bool IsSocket
  167. {
  168. get
  169. {
  170. return this.Attributes.IsSocket;
  171. }
  172. }
  173. /// <summary>
  174. /// Gets a value indicating whether file represents a symbolic link.
  175. /// </summary>
  176. /// <value>
  177. /// <c>true</c> if file represents a symbolic link; otherwise, <c>false</c>.
  178. /// </value>
  179. public bool IsSymbolicLink
  180. {
  181. get
  182. {
  183. return this.Attributes.IsSymbolicLink;
  184. }
  185. }
  186. /// <summary>
  187. /// Gets a value indicating whether file represents a regular file.
  188. /// </summary>
  189. /// <value>
  190. /// <c>true</c> if file represents a regular file; otherwise, <c>false</c>.
  191. /// </value>
  192. public bool IsRegularFile
  193. {
  194. get
  195. {
  196. return this.Attributes.IsRegularFile;
  197. }
  198. }
  199. /// <summary>
  200. /// Gets a value indicating whether file represents a block device.
  201. /// </summary>
  202. /// <value>
  203. /// <c>true</c> if file represents a block device; otherwise, <c>false</c>.
  204. /// </value>
  205. public bool IsBlockDevice
  206. {
  207. get
  208. {
  209. return this.Attributes.IsBlockDevice;
  210. }
  211. }
  212. /// <summary>
  213. /// Gets a value indicating whether file represents a directory.
  214. /// </summary>
  215. /// <value>
  216. /// <c>true</c> if file represents a directory; otherwise, <c>false</c>.
  217. /// </value>
  218. public bool IsDirectory
  219. {
  220. get
  221. {
  222. return this.Attributes.IsDirectory;
  223. }
  224. }
  225. /// <summary>
  226. /// Gets a value indicating whether file represents a character device.
  227. /// </summary>
  228. /// <value>
  229. /// <c>true</c> if file represents a character device; otherwise, <c>false</c>.
  230. /// </value>
  231. public bool IsCharacterDevice
  232. {
  233. get
  234. {
  235. return this.Attributes.IsCharacterDevice;
  236. }
  237. }
  238. /// <summary>
  239. /// Gets a value indicating whether file represents a named pipe.
  240. /// </summary>
  241. /// <value>
  242. /// <c>true</c> if file represents a named pipe; otherwise, <c>false</c>.
  243. /// </value>
  244. public bool IsNamedPipe
  245. {
  246. get
  247. {
  248. return this.Attributes.IsNamedPipe;
  249. }
  250. }
  251. /// <summary>
  252. /// Gets or sets a value indicating whether the owner can read from this file.
  253. /// </summary>
  254. /// <value>
  255. /// <c>true</c> if owner can read from this file; otherwise, <c>false</c>.
  256. /// </value>
  257. public bool OwnerCanRead
  258. {
  259. get
  260. {
  261. return this.Attributes.OwnerCanRead;
  262. }
  263. set
  264. {
  265. this.Attributes.OwnerCanRead = value;
  266. }
  267. }
  268. /// <summary>
  269. /// Gets or sets a value indicating whether the owner can write into this file.
  270. /// </summary>
  271. /// <value>
  272. /// <c>true</c> if owner can write into this file; otherwise, <c>false</c>.
  273. /// </value>
  274. public bool OwnerCanWrite
  275. {
  276. get
  277. {
  278. return this.Attributes.OwnerCanWrite;
  279. }
  280. set
  281. {
  282. this.Attributes.OwnerCanWrite = value;
  283. }
  284. }
  285. /// <summary>
  286. /// Gets or sets a value indicating whether the owner can execute this file.
  287. /// </summary>
  288. /// <value>
  289. /// <c>true</c> if owner can execute this file; otherwise, <c>false</c>.
  290. /// </value>
  291. public bool OwnerCanExecute
  292. {
  293. get
  294. {
  295. return this.Attributes.OwnerCanExecute;
  296. }
  297. set
  298. {
  299. this.Attributes.OwnerCanExecute = value;
  300. }
  301. }
  302. /// <summary>
  303. /// Gets or sets a value indicating whether the group members can read from this file.
  304. /// </summary>
  305. /// <value>
  306. /// <c>true</c> if group members can read from this file; otherwise, <c>false</c>.
  307. /// </value>
  308. public bool GroupCanRead
  309. {
  310. get
  311. {
  312. return this.Attributes.GroupCanRead;
  313. }
  314. set
  315. {
  316. this.Attributes.GroupCanRead = value;
  317. }
  318. }
  319. /// <summary>
  320. /// Gets or sets a value indicating whether the group members can write into this file.
  321. /// </summary>
  322. /// <value>
  323. /// <c>true</c> if group members can write into this file; otherwise, <c>false</c>.
  324. /// </value>
  325. public bool GroupCanWrite
  326. {
  327. get
  328. {
  329. return this.Attributes.GroupCanWrite;
  330. }
  331. set
  332. {
  333. this.Attributes.GroupCanWrite = value;
  334. }
  335. }
  336. /// <summary>
  337. /// Gets or sets a value indicating whether the group members can execute this file.
  338. /// </summary>
  339. /// <value>
  340. /// <c>true</c> if group members can execute this file; otherwise, <c>false</c>.
  341. /// </value>
  342. public bool GroupCanExecute
  343. {
  344. get
  345. {
  346. return this.Attributes.GroupCanExecute;
  347. }
  348. set
  349. {
  350. this.Attributes.GroupCanExecute = value;
  351. }
  352. }
  353. /// <summary>
  354. /// Gets or sets a value indicating whether the others can read from this file.
  355. /// </summary>
  356. /// <value>
  357. /// <c>true</c> if others can read from this file; otherwise, <c>false</c>.
  358. /// </value>
  359. public bool OthersCanRead
  360. {
  361. get
  362. {
  363. return this.Attributes.OthersCanRead;
  364. }
  365. set
  366. {
  367. this.Attributes.OthersCanRead = value;
  368. }
  369. }
  370. /// <summary>
  371. /// Gets or sets a value indicating whether the others can write into this file.
  372. /// </summary>
  373. /// <value>
  374. /// <c>true</c> if others can write into this file; otherwise, <c>false</c>.
  375. /// </value>
  376. public bool OthersCanWrite
  377. {
  378. get
  379. {
  380. return this.Attributes.OthersCanWrite;
  381. }
  382. set
  383. {
  384. this.Attributes.OthersCanWrite = value;
  385. }
  386. }
  387. /// <summary>
  388. /// Gets or sets a value indicating whether the others can execute this file.
  389. /// </summary>
  390. /// <value>
  391. /// <c>true</c> if others can execute this file; otherwise, <c>false</c>.
  392. /// </value>
  393. public bool OthersCanExecute
  394. {
  395. get
  396. {
  397. return this.Attributes.OthersCanExecute;
  398. }
  399. set
  400. {
  401. this.Attributes.OthersCanExecute = value;
  402. }
  403. }
  404. /// <summary>
  405. /// Gets the extension part of the file.
  406. /// </summary>
  407. /// <value>
  408. /// File extensions.
  409. /// </value>
  410. public IDictionary<string, string> Extensions { get; private set; }
  411. /// <summary>
  412. /// Sets file permissions.
  413. /// </summary>
  414. /// <param name="mode">The mode.</param>
  415. public void SetPermissions(short mode)
  416. {
  417. this.Attributes.SetPermissions(mode);
  418. this.UpdateStatus();
  419. }
  420. /// <summary>
  421. /// Permanently deletes a file on remote machine.
  422. /// </summary>
  423. public void Delete()
  424. {
  425. if (this.IsDirectory)
  426. {
  427. this._sftpSession.RequestRmDir(this.FullName);
  428. }
  429. else
  430. {
  431. this._sftpSession.RequestRemove(this.FullName);
  432. }
  433. }
  434. /// <summary>
  435. /// Moves a specified file to a new location on remote machine, providing the option to specify a new file name.
  436. /// </summary>
  437. /// <param name="destFileName">The path to move the file to, which can specify a different file name.</param>
  438. /// <exception cref="ArgumentNullException"><paramref name="destFileName"/> is null.</exception>
  439. public void MoveTo(string destFileName)
  440. {
  441. if (destFileName == null)
  442. throw new ArgumentNullException("destFileName");
  443. this._sftpSession.RequestRename(this.FullName, destFileName);
  444. var fullPath = this._sftpSession.GetCanonicalPath(destFileName);
  445. this.Name = fullPath.Substring(fullPath.LastIndexOf('/') + 1);
  446. this.FullName = fullPath;
  447. }
  448. /// <summary>
  449. /// Updates file status on the server.
  450. /// </summary>
  451. public void UpdateStatus()
  452. {
  453. this._sftpSession.RequestSetStat(this.FullName, this.Attributes);
  454. }
  455. /// <summary>
  456. /// Returns a <see cref="System.String"/> that represents this instance.
  457. /// </summary>
  458. /// <returns>
  459. /// A <see cref="System.String"/> that represents this instance.
  460. /// </returns>
  461. public override string ToString()
  462. {
  463. return string.Format(CultureInfo.CurrentCulture, "Name {0}, Length {1}, User ID {2}, Group ID {3}, Accessed {4}, Modified {5}", this.Name, this.Length, this.UserId, this.GroupId, this.LastAccessTime, this.LastWriteTime);
  464. }
  465. }
  466. }