1 | using System;
|
---|
2 | using System.IO;
|
---|
3 | using System.Xml;
|
---|
4 | using System.Text;
|
---|
5 | using System.Collections.Generic;
|
---|
6 | using System.Security.AccessControl;
|
---|
7 |
|
---|
8 | namespace SharpVectors.Converters.Utils
|
---|
9 | {
|
---|
10 | /// <summary>
|
---|
11 | /// Copies a file or a directory and its contents to a new location.
|
---|
12 | /// </summary>
|
---|
13 | [Serializable]
|
---|
14 | internal sealed class DirectoryCopier
|
---|
15 | {
|
---|
16 | #region Private Fields
|
---|
17 |
|
---|
18 | private int _copiedCount;
|
---|
19 | private bool _isOverwrite;
|
---|
20 | private bool _isRecursive;
|
---|
21 | private bool _includeHidden;
|
---|
22 | private bool _includeSecurity;
|
---|
23 |
|
---|
24 | #endregion
|
---|
25 |
|
---|
26 | #region Constructors and Destructor
|
---|
27 |
|
---|
28 | public DirectoryCopier()
|
---|
29 | {
|
---|
30 | _isOverwrite = true;
|
---|
31 | _isRecursive = true;
|
---|
32 | }
|
---|
33 |
|
---|
34 | public DirectoryCopier(DirectoryCopier source)
|
---|
35 | {
|
---|
36 | _copiedCount = source._copiedCount;
|
---|
37 | _isOverwrite = source._isOverwrite;
|
---|
38 | _isRecursive = source._isRecursive;
|
---|
39 | _includeHidden = source._includeHidden;
|
---|
40 | _includeSecurity = source._includeSecurity;
|
---|
41 | }
|
---|
42 |
|
---|
43 | #endregion
|
---|
44 |
|
---|
45 | #region Public Properties
|
---|
46 |
|
---|
47 | /// <summary>
|
---|
48 | /// Gets or sets a value indicating whether the directory copying is
|
---|
49 | /// recursive, that is includes the sub-directories.
|
---|
50 | /// </summary>
|
---|
51 | /// <value>
|
---|
52 | /// This property is <see langword="true"/> if the sub-directories are
|
---|
53 | /// included in the directory copy; otherwise, it is <see langword="false"/>.
|
---|
54 | /// The default is <see langword="true"/>.
|
---|
55 | /// </value>
|
---|
56 | public bool Recursive
|
---|
57 | {
|
---|
58 | get
|
---|
59 | {
|
---|
60 | return _isRecursive;
|
---|
61 | }
|
---|
62 |
|
---|
63 | set
|
---|
64 | {
|
---|
65 | _isRecursive = value;
|
---|
66 | }
|
---|
67 | }
|
---|
68 |
|
---|
69 | /// <summary>
|
---|
70 | /// Gets or sets a value indicating whether an existing file is overwritten.
|
---|
71 | /// </summary>
|
---|
72 | /// <value>
|
---|
73 | /// This property is <see langword="true"/> if existing file is overwritten;
|
---|
74 | /// otherwise, it is <see langword="false"/>. The default is <see langword="true"/>.
|
---|
75 | /// </value>
|
---|
76 | public bool Overwrite
|
---|
77 | {
|
---|
78 | get
|
---|
79 | {
|
---|
80 | return _isOverwrite;
|
---|
81 | }
|
---|
82 |
|
---|
83 | set
|
---|
84 | {
|
---|
85 | _isOverwrite = value;
|
---|
86 | }
|
---|
87 | }
|
---|
88 |
|
---|
89 | /// <summary>
|
---|
90 | /// Gets or sets a value indicating whether the security settings of the
|
---|
91 | /// copied file is retained.
|
---|
92 | /// </summary>
|
---|
93 | /// <value>
|
---|
94 | /// This property is <see langword="true"/> if the security settings of the
|
---|
95 | /// file is also copied; otherwise, it is <see langword="false"/>. The
|
---|
96 | /// default is <see langword="false"/>.
|
---|
97 | /// </value>
|
---|
98 | public bool IncludeSecurity
|
---|
99 | {
|
---|
100 | get
|
---|
101 | {
|
---|
102 | return _includeSecurity;
|
---|
103 | }
|
---|
104 |
|
---|
105 | set
|
---|
106 | {
|
---|
107 | _includeSecurity = value;
|
---|
108 | }
|
---|
109 | }
|
---|
110 |
|
---|
111 | /// <summary>
|
---|
112 | /// Gets or sets a value indicating whether the copy operation includes
|
---|
113 | /// hidden directories and files.
|
---|
114 | /// </summary>
|
---|
115 | /// <value>
|
---|
116 | /// This property is <see langword="true"/> if hidden directories and files
|
---|
117 | /// are included in the copy operation; otherwise, it is
|
---|
118 | /// <see langword="false"/>. The default is <see langword="false"/>.
|
---|
119 | /// </value>
|
---|
120 | public bool IncludeHidden
|
---|
121 | {
|
---|
122 | get
|
---|
123 | {
|
---|
124 | return _includeHidden;
|
---|
125 | }
|
---|
126 |
|
---|
127 | set
|
---|
128 | {
|
---|
129 | _includeHidden = value;
|
---|
130 | }
|
---|
131 | }
|
---|
132 |
|
---|
133 | #endregion
|
---|
134 |
|
---|
135 | #region Public Methods
|
---|
136 |
|
---|
137 | /// <summary>
|
---|
138 | ///
|
---|
139 | /// </summary>
|
---|
140 | /// <param name="sourceDir">
|
---|
141 | /// The path of the file or directory to copy.
|
---|
142 | /// </param>
|
---|
143 | /// <param name="targetDir">
|
---|
144 | /// The path to the new location.
|
---|
145 | /// </param>
|
---|
146 | public int Copy(string sourceDir, string targetDir)
|
---|
147 | {
|
---|
148 | _copiedCount = 0;
|
---|
149 |
|
---|
150 | if (sourceDir == null)
|
---|
151 | {
|
---|
152 | throw new ArgumentNullException("sourceDir");
|
---|
153 | }
|
---|
154 | if (sourceDir.Length == 0)
|
---|
155 | {
|
---|
156 | throw new ArgumentException("sourceDir");
|
---|
157 | }
|
---|
158 | if (!Directory.Exists(sourceDir))
|
---|
159 | {
|
---|
160 | throw new InvalidOperationException();
|
---|
161 | }
|
---|
162 |
|
---|
163 | if (targetDir == null)
|
---|
164 | {
|
---|
165 | throw new ArgumentNullException("targetDir");
|
---|
166 | }
|
---|
167 | if (targetDir.Length == 0)
|
---|
168 | {
|
---|
169 | throw new ArgumentException("targetDir");
|
---|
170 | }
|
---|
171 |
|
---|
172 | if (String.Equals(sourceDir, targetDir,
|
---|
173 | StringComparison.CurrentCultureIgnoreCase))
|
---|
174 | {
|
---|
175 | throw new InvalidOperationException();
|
---|
176 | }
|
---|
177 |
|
---|
178 | DirectoryInfo sourceInfo = new DirectoryInfo(sourceDir);
|
---|
179 | DirectoryInfo targetInfo = new DirectoryInfo(targetDir);
|
---|
180 | DirectorySecurity dirSecurity = null;
|
---|
181 | if (_includeSecurity)
|
---|
182 | {
|
---|
183 | dirSecurity = sourceInfo.GetAccessControl();
|
---|
184 | }
|
---|
185 | if (!targetInfo.Exists)
|
---|
186 | {
|
---|
187 | if (dirSecurity != null)
|
---|
188 | {
|
---|
189 | targetInfo.Create(dirSecurity);
|
---|
190 | }
|
---|
191 | else
|
---|
192 | {
|
---|
193 | targetInfo.Create();
|
---|
194 | }
|
---|
195 | targetInfo.Attributes = sourceInfo.Attributes;
|
---|
196 | }
|
---|
197 | else
|
---|
198 | {
|
---|
199 | if (dirSecurity != null)
|
---|
200 | {
|
---|
201 | targetInfo.SetAccessControl(dirSecurity);
|
---|
202 | }
|
---|
203 | }
|
---|
204 |
|
---|
205 | Copy(sourceInfo, targetInfo);
|
---|
206 |
|
---|
207 | return _copiedCount;
|
---|
208 | }
|
---|
209 |
|
---|
210 | #endregion
|
---|
211 |
|
---|
212 | #region Private Methods
|
---|
213 |
|
---|
214 | private void Copy(DirectoryInfo source, DirectoryInfo target)
|
---|
215 | {
|
---|
216 | CopyFiles(source, target);
|
---|
217 |
|
---|
218 | if (!_isRecursive)
|
---|
219 | {
|
---|
220 | return;
|
---|
221 | }
|
---|
222 |
|
---|
223 | DirectoryInfo[] arrSourceInfo = source.GetDirectories();
|
---|
224 |
|
---|
225 | int dirCount = (arrSourceInfo == null) ? 0 : arrSourceInfo.Length;
|
---|
226 |
|
---|
227 | for (int i = 0; i < dirCount; i++)
|
---|
228 | {
|
---|
229 | DirectoryInfo sourceInfo = arrSourceInfo[i];
|
---|
230 | FileAttributes fileAttr = sourceInfo.Attributes;
|
---|
231 | if (!_includeHidden)
|
---|
232 | {
|
---|
233 | if ((fileAttr & FileAttributes.Hidden) == FileAttributes.Hidden)
|
---|
234 | {
|
---|
235 | continue;
|
---|
236 | }
|
---|
237 | }
|
---|
238 |
|
---|
239 | DirectoryInfo targetInfo = null;
|
---|
240 | if (_includeSecurity)
|
---|
241 | {
|
---|
242 | targetInfo = target.CreateSubdirectory(sourceInfo.Name,
|
---|
243 | sourceInfo.GetAccessControl());
|
---|
244 | }
|
---|
245 | else
|
---|
246 | {
|
---|
247 | targetInfo = target.CreateSubdirectory(sourceInfo.Name);
|
---|
248 | }
|
---|
249 | targetInfo.Attributes = fileAttr;
|
---|
250 |
|
---|
251 | Copy(sourceInfo, targetInfo);
|
---|
252 | }
|
---|
253 | }
|
---|
254 |
|
---|
255 | private void CopyFiles(DirectoryInfo source, DirectoryInfo target)
|
---|
256 | {
|
---|
257 | FileInfo[] listInfo = source.GetFiles();
|
---|
258 |
|
---|
259 | int fileCount = (listInfo == null) ? 0 : listInfo.Length;
|
---|
260 |
|
---|
261 | string targetDirName = target.ToString();
|
---|
262 | string filePath;
|
---|
263 |
|
---|
264 | // Handle the copy of each file into it's new directory.
|
---|
265 | for (int i = 0; i < fileCount; i++)
|
---|
266 | {
|
---|
267 | FileInfo fi = listInfo[i];
|
---|
268 | FileAttributes fileAttr = fi.Attributes;
|
---|
269 | if (!_includeHidden)
|
---|
270 | {
|
---|
271 | if ((fileAttr & FileAttributes.Hidden) == FileAttributes.Hidden)
|
---|
272 | {
|
---|
273 | continue;
|
---|
274 | }
|
---|
275 | }
|
---|
276 |
|
---|
277 | _copiedCount++;
|
---|
278 |
|
---|
279 | filePath = Path.Combine(targetDirName, fi.Name);
|
---|
280 |
|
---|
281 | fi.CopyTo(filePath, _isOverwrite);
|
---|
282 |
|
---|
283 | File.SetAttributes(filePath, fileAttr);
|
---|
284 | // if required to set the security or access control
|
---|
285 | if (_includeSecurity)
|
---|
286 | {
|
---|
287 | File.SetAccessControl(filePath, fi.GetAccessControl());
|
---|
288 | }
|
---|
289 | }
|
---|
290 | }
|
---|
291 |
|
---|
292 | #endregion
|
---|
293 | }
|
---|
294 | }
|
---|