using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Collections.Generic;
using System.Security.AccessControl;
namespace SharpVectors.Converters.Utils
{
///
/// Copies a file or a directory and its contents to a new location.
///
[Serializable]
internal sealed class DirectoryCopier
{
#region Private Fields
private int _copiedCount;
private bool _isOverwrite;
private bool _isRecursive;
private bool _includeHidden;
private bool _includeSecurity;
#endregion
#region Constructors and Destructor
public DirectoryCopier()
{
_isOverwrite = true;
_isRecursive = true;
}
public DirectoryCopier(DirectoryCopier source)
{
_copiedCount = source._copiedCount;
_isOverwrite = source._isOverwrite;
_isRecursive = source._isRecursive;
_includeHidden = source._includeHidden;
_includeSecurity = source._includeSecurity;
}
#endregion
#region Public Properties
///
/// Gets or sets a value indicating whether the directory copying is
/// recursive, that is includes the sub-directories.
///
///
/// This property is if the sub-directories are
/// included in the directory copy; otherwise, it is .
/// The default is .
///
public bool Recursive
{
get
{
return _isRecursive;
}
set
{
_isRecursive = value;
}
}
///
/// Gets or sets a value indicating whether an existing file is overwritten.
///
///
/// This property is if existing file is overwritten;
/// otherwise, it is . The default is .
///
public bool Overwrite
{
get
{
return _isOverwrite;
}
set
{
_isOverwrite = value;
}
}
///
/// Gets or sets a value indicating whether the security settings of the
/// copied file is retained.
///
///
/// This property is if the security settings of the
/// file is also copied; otherwise, it is . The
/// default is .
///
public bool IncludeSecurity
{
get
{
return _includeSecurity;
}
set
{
_includeSecurity = value;
}
}
///
/// Gets or sets a value indicating whether the copy operation includes
/// hidden directories and files.
///
///
/// This property is if hidden directories and files
/// are included in the copy operation; otherwise, it is
/// . The default is .
///
public bool IncludeHidden
{
get
{
return _includeHidden;
}
set
{
_includeHidden = value;
}
}
#endregion
#region Public Methods
///
///
///
///
/// The path of the file or directory to copy.
///
///
/// The path to the new location.
///
public int Copy(string sourceDir, string targetDir)
{
_copiedCount = 0;
if (sourceDir == null)
{
throw new ArgumentNullException("sourceDir");
}
if (sourceDir.Length == 0)
{
throw new ArgumentException("sourceDir");
}
if (!Directory.Exists(sourceDir))
{
throw new InvalidOperationException();
}
if (targetDir == null)
{
throw new ArgumentNullException("targetDir");
}
if (targetDir.Length == 0)
{
throw new ArgumentException("targetDir");
}
if (String.Equals(sourceDir, targetDir,
StringComparison.CurrentCultureIgnoreCase))
{
throw new InvalidOperationException();
}
DirectoryInfo sourceInfo = new DirectoryInfo(sourceDir);
DirectoryInfo targetInfo = new DirectoryInfo(targetDir);
DirectorySecurity dirSecurity = null;
if (_includeSecurity)
{
dirSecurity = sourceInfo.GetAccessControl();
}
if (!targetInfo.Exists)
{
if (dirSecurity != null)
{
targetInfo.Create(dirSecurity);
}
else
{
targetInfo.Create();
}
targetInfo.Attributes = sourceInfo.Attributes;
}
else
{
if (dirSecurity != null)
{
targetInfo.SetAccessControl(dirSecurity);
}
}
Copy(sourceInfo, targetInfo);
return _copiedCount;
}
#endregion
#region Private Methods
private void Copy(DirectoryInfo source, DirectoryInfo target)
{
CopyFiles(source, target);
if (!_isRecursive)
{
return;
}
DirectoryInfo[] arrSourceInfo = source.GetDirectories();
int dirCount = (arrSourceInfo == null) ? 0 : arrSourceInfo.Length;
for (int i = 0; i < dirCount; i++)
{
DirectoryInfo sourceInfo = arrSourceInfo[i];
FileAttributes fileAttr = sourceInfo.Attributes;
if (!_includeHidden)
{
if ((fileAttr & FileAttributes.Hidden) == FileAttributes.Hidden)
{
continue;
}
}
DirectoryInfo targetInfo = null;
if (_includeSecurity)
{
targetInfo = target.CreateSubdirectory(sourceInfo.Name,
sourceInfo.GetAccessControl());
}
else
{
targetInfo = target.CreateSubdirectory(sourceInfo.Name);
}
targetInfo.Attributes = fileAttr;
Copy(sourceInfo, targetInfo);
}
}
private void CopyFiles(DirectoryInfo source, DirectoryInfo target)
{
FileInfo[] listInfo = source.GetFiles();
int fileCount = (listInfo == null) ? 0 : listInfo.Length;
string targetDirName = target.ToString();
string filePath;
// Handle the copy of each file into it's new directory.
for (int i = 0; i < fileCount; i++)
{
FileInfo fi = listInfo[i];
FileAttributes fileAttr = fi.Attributes;
if (!_includeHidden)
{
if ((fileAttr & FileAttributes.Hidden) == FileAttributes.Hidden)
{
continue;
}
}
_copiedCount++;
filePath = Path.Combine(targetDirName, fi.Name);
fi.CopyTo(filePath, _isOverwrite);
File.SetAttributes(filePath, fileAttr);
// if required to set the security or access control
if (_includeSecurity)
{
File.SetAccessControl(filePath, fi.GetAccessControl());
}
}
}
#endregion
}
}