PageRenderTime 49ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/sys/dotnet/fan/sys/File.cs

https://bitbucket.org/bedlaczech/fan-1.0
C# | 428 lines | 305 code | 79 blank | 44 comment | 52 complexity | a48656067dd1c1d4fe3c057ee0f79ba4 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. //
  2. // Copyright (c) 2007, Brian Frank and Andy Frank
  3. // Licensed under the Academic Free License version 3.0
  4. //
  5. // History:
  6. // 16 Jan 07 Andy Frank Creation
  7. //
  8. namespace Fan.Sys
  9. {
  10. /// <summary>
  11. /// File represents a file or directory in a file system.
  12. /// <summary>
  13. public abstract class File : FanObj
  14. {
  15. //////////////////////////////////////////////////////////////////////////
  16. // Construction
  17. //////////////////////////////////////////////////////////////////////////
  18. public static File make(Uri uri) { return make(uri, true); }
  19. public static File make(Uri uri, bool checkSlash)
  20. {
  21. System.IO.FileSystemInfo f = LocalFile.uriToFile(uri);
  22. if (f is System.IO.DirectoryInfo && !checkSlash && !uri.isDir())
  23. uri = uri.plusSlash();
  24. return new LocalFile(uri, f);
  25. }
  26. public static File os(string osPath)
  27. {
  28. System.IO.FileSystemInfo f = (System.IO.Directory.Exists(osPath))
  29. ? new System.IO.DirectoryInfo(osPath) as System.IO.FileSystemInfo
  30. : new System.IO.FileInfo(osPath) as System.IO.FileSystemInfo;
  31. Uri uri = LocalFile.pathToUri(osPath, f is System.IO.DirectoryInfo);
  32. return new LocalFile(uri, f);
  33. }
  34. public static List osRoots()
  35. {
  36. List list = new List(Sys.FileType);
  37. string[] drives = System.IO.Directory.GetLogicalDrives();
  38. for (int i=0; i<drives.Length; i++)
  39. list.add(new LocalFile(new System.IO.FileInfo(drives[i]), true));
  40. return list;
  41. }
  42. public static File createTemp() { return createTemp(null, null, null); }
  43. public static File createTemp(string prefix) { return createTemp(prefix, null, null); }
  44. public static File createTemp(string prefix, string suffix) { return createTemp(prefix, suffix, null); }
  45. public static File createTemp(string prefix, string suffix, File dir)
  46. {
  47. if (prefix == null || prefix.Length == 0) prefix = "fan";
  48. if (suffix == null) suffix = ".tmp";
  49. string parent = null;
  50. if (dir == null)
  51. {
  52. parent = System.IO.Path.GetTempPath();
  53. }
  54. else
  55. {
  56. if (!(dir is LocalFile)) throw IOErr.make("Dir is not on local file system: " + dir).val;
  57. parent = ((LocalFile)dir).m_file.FullName;
  58. }
  59. try
  60. {
  61. string name = parent + '\\' + prefix + suffix;
  62. int count = 1;
  63. while (System.IO.File.Exists(name))
  64. name = parent + '\\' + prefix + (count++) + suffix;
  65. LocalFile temp = new LocalFile(new System.IO.FileInfo(name));
  66. temp.create();
  67. return temp;
  68. }
  69. catch (System.IO.IOException e)
  70. {
  71. throw IOErr.make(e).val;
  72. }
  73. }
  74. protected File(Uri uri)
  75. {
  76. this.m_uri = uri;
  77. }
  78. //////////////////////////////////////////////////////////////////////////
  79. // Identity
  80. //////////////////////////////////////////////////////////////////////////
  81. public override sealed bool Equals(object obj)
  82. {
  83. if (obj is File)
  84. {
  85. return m_uri.Equals(((File)obj).m_uri);
  86. }
  87. return false;
  88. }
  89. public override sealed int GetHashCode() { return m_uri.GetHashCode(); }
  90. public override sealed long hash() { return m_uri.hash(); }
  91. public override sealed string toStr() { return m_uri.toStr(); }
  92. public override Type @typeof() { return Sys.FileType; }
  93. //////////////////////////////////////////////////////////////////////////
  94. // Uri
  95. //////////////////////////////////////////////////////////////////////////
  96. public Uri uri() { return m_uri; }
  97. public bool isDir() { return m_uri.isDir(); }
  98. public List path() { return m_uri.path(); }
  99. public string pathStr() { return m_uri.pathStr(); }
  100. public string name() { return m_uri.name(); }
  101. public string basename() { return m_uri.basename(); }
  102. public string ext() { return m_uri.ext(); }
  103. public MimeType mimeType() { return m_uri.mimeType(); }
  104. //////////////////////////////////////////////////////////////////////////
  105. // Access
  106. //////////////////////////////////////////////////////////////////////////
  107. public abstract bool exists();
  108. public abstract Long size();
  109. public virtual bool isEmpty()
  110. {
  111. if (isDir()) return list().isEmpty();
  112. Long size = this.size();
  113. return size == null || size.longValue() <= 0;
  114. }
  115. public abstract DateTime modified();
  116. public abstract void modified(DateTime time);
  117. public abstract string osPath();
  118. public abstract File parent();
  119. public abstract List list();
  120. public virtual List listDirs()
  121. {
  122. List x = list();
  123. for (int i=x.sz()-1; i>=0; --i)
  124. if (!((File)x.get(i)).isDir())
  125. x.removeAt(i);
  126. return x;
  127. }
  128. public virtual void walk(Func c)
  129. {
  130. c.call(this);
  131. if (isDir())
  132. {
  133. List x = list();
  134. for (int i=0; i<x.sz(); ++i)
  135. ((File)x.get(i)).walk(c);
  136. }
  137. }
  138. public virtual List listFiles()
  139. {
  140. List x = list();
  141. for (int i=x.sz()-1; i>=0; --i)
  142. if (((File)x.get(i)).isDir())
  143. x.removeAt(i);
  144. return x;
  145. }
  146. public abstract File normalize();
  147. public File plus(Uri uri) { return plus(uri, true); }
  148. public abstract File plus(Uri uri, bool checkSlash);
  149. internal File plus(string uri) { return plus(Uri.fromStr(uri)); }
  150. internal File plusNameOf(File x)
  151. {
  152. string name = x.name();
  153. if (x.isDir()) name += "/";
  154. return plus(name);
  155. }
  156. //////////////////////////////////////////////////////////////////////////
  157. // Management
  158. //////////////////////////////////////////////////////////////////////////
  159. public abstract File create();
  160. public File createFile(string name)
  161. {
  162. if (!isDir()) throw IOErr.make("Not a directory: " + this).val;
  163. return this.plus(FanStr.toUri(name)).create();
  164. }
  165. public File createDir(string name)
  166. {
  167. if (!isDir()) throw IOErr.make("Not a directory: " + this).val;
  168. if (!name.EndsWith("/")) name = name + "/";
  169. return this.plus(FanStr.toUri(name)).create();
  170. }
  171. public abstract void delete();
  172. public abstract File deleteOnExit();
  173. //////////////////////////////////////////////////////////////////////////
  174. // Copy
  175. //////////////////////////////////////////////////////////////////////////
  176. public File copyTo(File to) { return copyTo(to, null); }
  177. public virtual File copyTo(File to, Map options)
  178. {
  179. // sanity
  180. if (isDir() != to.isDir())
  181. {
  182. if (isDir())
  183. throw ArgErr.make("copyTo must be dir `" + to + "`").val;
  184. else
  185. throw ArgErr.make("copyTo must not be dir `" + to + "`").val;
  186. }
  187. // options
  188. object exclude = null, overwrite = null;
  189. if (options != null)
  190. {
  191. exclude = options.get(optExclude);
  192. overwrite = options.get(optOverwrite);
  193. }
  194. // recurse
  195. doCopyTo(to, exclude, overwrite);
  196. return to;
  197. }
  198. private void doCopyTo(File to, object exclude, object overwrite)
  199. {
  200. // check exclude
  201. if (exclude is Regex)
  202. {
  203. if (((Regex)exclude).matches(m_uri.toStr())) return;
  204. }
  205. else if (exclude is Func)
  206. {
  207. if (((Func)exclude).call(this) == Boolean.True) return;
  208. }
  209. // check for overwrite
  210. if (to.exists())
  211. {
  212. if (overwrite is Boolean)
  213. {
  214. if (overwrite == Boolean.False) return;
  215. }
  216. else if (overwrite is Func)
  217. {
  218. if (((Func)overwrite).call(this) == Boolean.False) return;
  219. }
  220. else
  221. {
  222. throw IOErr.make("No overwrite policy for `" + to + "`").val;
  223. }
  224. }
  225. // copy directory
  226. if (isDir())
  227. {
  228. to.create();
  229. List kids = list();
  230. for (int i=0; i<kids.sz(); ++i)
  231. {
  232. File kid = (File)kids.get(i);
  233. kid.doCopyTo(to.plusNameOf(kid), exclude, overwrite);
  234. }
  235. }
  236. // copy file contents
  237. else
  238. {
  239. OutStream @out = to.@out();
  240. try
  241. {
  242. @in().pipe(@out);
  243. }
  244. finally
  245. {
  246. @out.close();
  247. }
  248. }
  249. }
  250. public File copyInto(File dir) { return copyInto(dir, null); }
  251. public virtual File copyInto(File dir, Map options)
  252. {
  253. if (!dir.isDir())
  254. throw ArgErr.make("Not a dir: `" + dir + "`").val;
  255. return copyTo(dir.plusNameOf(this), options);
  256. }
  257. //////////////////////////////////////////////////////////////////////////
  258. // Move
  259. //////////////////////////////////////////////////////////////////////////
  260. public abstract File moveTo(File to);
  261. public virtual File moveInto(File dir)
  262. {
  263. if (!dir.isDir())
  264. throw ArgErr.make("Not a dir: `" + dir + "`").val;
  265. return moveTo(dir.plusNameOf(this));
  266. }
  267. public virtual File rename(string newName)
  268. {
  269. string n = newName;
  270. if (isDir()) n += "/";
  271. return moveTo(parent().plus(n));
  272. }
  273. //////////////////////////////////////////////////////////////////////////
  274. // IO
  275. //////////////////////////////////////////////////////////////////////////
  276. public Buf open() { return open(rwStr); }
  277. public abstract Buf open(string mode);
  278. public Buf mmap() { return mmap(rwStr, 0, null); }
  279. public Buf mmap(string mode) { return mmap(mode, 0, null); }
  280. public Buf mmap(string mode, long pos) { return mmap(mode, pos, null); }
  281. public abstract Buf mmap(string mode, long pos, Long size);
  282. public InStream @in() { return @in(defaultBufSize); }
  283. public abstract InStream @in(Long bufSize);
  284. public OutStream @out() { return @out(false, defaultBufSize); }
  285. public OutStream @out(bool append) { return @out(append, defaultBufSize); }
  286. public abstract OutStream @out(bool append, Long bufSize);
  287. private static readonly Long defaultBufSize = Long.valueOf(4096);
  288. public Buf readAllBuf()
  289. {
  290. return @in(defaultBufSize).readAllBuf();
  291. }
  292. public List readAllLines()
  293. {
  294. return @in(defaultBufSize).readAllLines();
  295. }
  296. public void eachLine(Func f)
  297. {
  298. @in(FanInt.Chunk).eachLine(f);
  299. }
  300. public string readAllStr() { return readAllStr(true); }
  301. public string readAllStr(bool normalizeNewlines)
  302. {
  303. return @in(defaultBufSize).readAllStr(normalizeNewlines);
  304. }
  305. public Map readProps()
  306. {
  307. return @in(defaultBufSize).readProps();
  308. }
  309. public void writeProps(Map props)
  310. {
  311. @out(false, defaultBufSize).writeProps(props, true);
  312. }
  313. public object readObj() { return readObj(null); }
  314. public object readObj(Map options)
  315. {
  316. InStream ins = @in();
  317. try
  318. {
  319. return ins.readObj(options);
  320. }
  321. finally
  322. {
  323. ins.close();
  324. }
  325. }
  326. public void writeObj(object obj) { writeObj(obj, null); }
  327. public void writeObj(object obj, Map options)
  328. {
  329. OutStream outs = @out();
  330. try
  331. {
  332. outs.writeObj(obj, options);
  333. }
  334. finally
  335. {
  336. outs.close();
  337. }
  338. }
  339. //////////////////////////////////////////////////////////////////////////
  340. // Fields
  341. //////////////////////////////////////////////////////////////////////////
  342. public static readonly string m_sep = ""+System.IO.Path.DirectorySeparatorChar;
  343. public static readonly string m_pathSep = ""+System.IO.Path.PathSeparator;
  344. internal static readonly string rwStr = "rw";
  345. internal static readonly string optOverwrite = "overwrite";
  346. internal static readonly string optExclude = "exclude";
  347. internal readonly Uri m_uri;
  348. }
  349. }