예제 #1
0
        private void CopySourceToDestination(CopyItem item, OrganizeSummary summary)
        {
            string destinationDirectory = Path.GetDirectoryName(item.destinationPath);

            if (!Directory.Exists(destinationDirectory))
            {
                try
                {
                    Directory.CreateDirectory(destinationDirectory);
                }
                catch (Exception ex)
                {
                    if (ExceptionHandling == ExceptionHandling.Throw)
                    {
                        throw new MediaOrganizerException($"Failed to create directory: {destinationDirectory}", ex);
                    }

                    Trace.WriteLine($"[{nameof(MediaOrganizer)}] Ignored exception: {ex.Message}");
                    return;
                }
            }

            summary.sources.Add(item.sourcePath);
            summary.destinations.Add(item.destinationPath);

            bool   overwrite             = false;
            string targetDestinationPath = item.destinationPath; // Note: path may be altered later on to resolve conflicts
            bool   fileExists            = File.Exists(targetDestinationPath);

            switch (CopyMode)
            {
            case CopyMode.OverwriteExisting:
                overwrite = true;
                if (fileExists)
                {
                    summary.overwritten[item.sourcePath] = targetDestinationPath;
                    Trace.WriteLine($"[{nameof(MediaOrganizer)}] Force overwrite file: {targetDestinationPath}");
                }
                break;

            case CopyMode.KeepExisting:
                if (fileExists)
                {
                    summary.skipped[item.sourcePath] = targetDestinationPath;
                    Trace.WriteLine($"[{nameof(MediaOrganizer)}] Keep existing file: {targetDestinationPath}");
                    return;
                }
                break;

            case CopyMode.KeepUnique:
                FileInfo sourceInfo      = item.sourceInfo;
                FileInfo destinationInfo = new FileInfo(targetDestinationPath);
                if (fileExists)
                {
                    // Potentially slow, therefore previous optimizations
                    if (sourceInfo.AreFilesIdentical(destinationInfo, FileComparator))
                    {
                        summary.duplicates[item.sourcePath] = targetDestinationPath;
                        Trace.WriteLine($"[{nameof(MediaOrganizer)}] Duplicate file ignored: {item.sourcePath} (duplicate of {targetDestinationPath})");
                        return;
                    }
                }

                if (sourceInfo.FileExistsInDirectory(destinationInfo.Directory, FileComparator))
                {
                    summary.duplicates[item.sourcePath] = destinationInfo.Directory.FullName;
                    Trace.WriteLine($"[{nameof(MediaOrganizer)}] Duplicate file ignored: {item.sourcePath} (exists in {destinationInfo.Directory})");
                    return;     // Source file already exists in target directory
                }

                // Find next unused filename
                string originalDestinationPath = targetDestinationPath;
                int    index = 1;
                while (fileExists)
                {
                    targetDestinationPath = destinationInfo.SuffixFileName(index++);
                    fileExists            = File.Exists(targetDestinationPath);
                }
                if (targetDestinationPath != originalDestinationPath)
                {
                    summary.renamed[originalDestinationPath] = targetDestinationPath;
                    Trace.WriteLine($"[{nameof(MediaOrganizer)}] Renamed to prevent conflict: {targetDestinationPath} (original: {originalDestinationPath})");
                }
                break;

            default:
                throw new NotImplementedException($"CopyMode: {CopyMode}");
            }

            try
            {
                File.Copy(item.sourcePath, targetDestinationPath, overwrite);
                summary.modified.Add(targetDestinationPath);
                if (FileVerification != FileComparator.None)
                {
                    if (!item.sourceInfo.AreFilesIdentical(new FileInfo(targetDestinationPath), FileVerification))
                    {
                        throw new MediaOrganizerException("File verification failed. Source: {0}. Destination: {1}", item.sourcePath, targetDestinationPath);
                    }
                }
            }
            catch (Exception ex)
            {
                if (ExceptionHandling == ExceptionHandling.Throw)
                {
                    throw new MediaOrganizerException($"Failed to copy file. Mode: {CopyMode}. Overwrite: {overwrite}. Source: {item.sourcePath}. Destination: {targetDestinationPath}", ex);
                }

                Trace.WriteLine($"[{nameof(MediaOrganizer)}] Ignored exception: {ex.Message}");
            }
        }