Exemplo n.º 1
0
        /// <summary>
        /// Moves a file filtering its content through the filter chain.
        /// </summary>
        /// <param name="sourceFileName">
        /// The file to move.
        /// </param>
        /// <param name="destFileName">
        /// The file to move move to.
        /// </param>
        /// <param name="filterChain">
        /// Chain of filters to apply when moving, or <see langword="null" /> is no
        /// filters should be applied.
        /// </param>
        /// <param name="inputEncoding">
        /// The encoding used to read the soure file.
        /// </param>
        /// <param name="outputEncoding">
        /// The encoding used to write the destination file.
        /// </param>
        public static void MoveFile(
            string sourceFileName,
            string destFileName,
            FilterChain filterChain,
            Encoding inputEncoding,
            Encoding outputEncoding)
        {
            // If the source file does not exist, throw an exception.
            if (!File.Exists(sourceFileName))
            {
                throw new BuildException(
                          String.Format("Cannot move file: Source File {0} does not exist",
                                        sourceFileName));
            }

            // if no filters have been defined, and no input or output encoding
            // is set, we can just use the File.Move method
            if (FilterChain.IsNullOrEmpty(filterChain) &&
                inputEncoding == null && outputEncoding == null)
            {
                File.Move(sourceFileName, destFileName);
            }
            else
            {
                CopyFile(sourceFileName, destFileName, filterChain, inputEncoding, outputEncoding);
                File.Delete(sourceFileName);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Executes the Copy task.
        /// </summary>
        /// <exception cref="BuildException">A file that has to be copied does not exist or could not be copied.</exception>
        protected override void ExecuteTask()
        {
            // ensure base directory is set, even if fileset was not initialized
            // from XML
            if (CopyFileSet.BaseDirectory == null)
            {
                CopyFileSet.BaseDirectory = new DirectoryInfo(Project.BaseDirectory);
            }

            // Clear previous copied files
            _fileCopyMap.Clear();

            // if the source file is specified, check to see whether it is a file or directory before proceeding
            if (SourceFile != null)
            {
                // copy a single file.
                if (SourceFile.Exists)
                {
                    FileInfo dstInfo = null;
                    if (ToFile != null)
                    {
                        dstInfo = ToFile;
                    }
                    else
                    {
                        string dstFilePath = Path.Combine(ToDirectory.FullName,
                                                          SourceFile.Name);
                        dstInfo = new FileInfo(dstFilePath);
                    }

                    // do the outdated check
                    bool outdated = (!dstInfo.Exists) || (SourceFile.LastWriteTime > dstInfo.LastWriteTime);

                    if (Overwrite || outdated)
                    {
                        // add to a copy map of absolute verified paths
                        FileCopyMap.Add(dstInfo.FullName, new FileDateInfo(SourceFile.FullName, SourceFile.LastWriteTime));
                        _fileCount++;

                        if (dstInfo.Exists && dstInfo.Attributes != FileAttributes.Normal)
                        {
                            File.SetAttributes(dstInfo.FullName, FileAttributes.Normal);
                        }
                    }
                }
                // If SourceFile exists as a directory, proceed with moving the specified directory
                else if (!SourceFile.Exists && Directory.Exists(SourceFile.FullName))
                {
                    // Stage the directory names
                    string sourceDirName = SourceFile.FullName;
                    string destDirName;

                    // If ToFile was specified, make sure the specified filename does not exist
                    // as a file or a directory.
                    if (ToFile != null)
                    {
                        if (ToFile.Exists)
                        {
                            throw new BuildException(String.Format(CultureInfo.InvariantCulture,
                                                                   "Cannot move directory '{0}' to an existing file '{1}'",
                                                                   SourceFile.FullName, ToFile.FullName), Location);
                        }
                        if (Directory.Exists(ToFile.FullName))
                        {
                            throw new BuildException(String.Format(CultureInfo.InvariantCulture,
                                                                   "Cannot move directory '{0}' to an existing directory '{1}'",
                                                                   SourceFile.FullName, ToFile.FullName), Location);
                        }
                        destDirName = ToFile.FullName;
                    }
                    // If ToDirectory was specified, make sure the specified directory does not
                    // exist.
                    else if (ToDirectory != null)
                    {
                        if (ToDirectory.Exists)
                        {
                            throw new BuildException(String.Format(CultureInfo.InvariantCulture,
                                                                   "Cannot move directory '{0}' to an existing directory '{1}'",
                                                                   SourceFile.FullName, ToDirectory.FullName), Location);
                        }
                        destDirName = ToDirectory.FullName;
                    }
                    // Else, throw an exception
                    else
                    {
                        throw new BuildException("Target directory name not specified",
                                                 Location);
                    }
                    FileCopyMap.Add(destDirName, new FileDateInfo(sourceDirName, SourceFile.LastWriteTime, true));
                    _dirCount++;
                }
                else
                {
                    throw CreateSourceFileNotFoundException(SourceFile.FullName);
                }
            }

            // copy file set contents.
            else
            {
                // get the complete path of the base directory of the fileset, ie, c:\work\nant\src
                DirectoryInfo srcBaseInfo = CopyFileSet.BaseDirectory;

                // Check to see if the file operation is a straight pass through (ie: no file or
                // directory modifications) before proceeding.
                bool completeDir = true;

                // completeDir criteria
                bool[] dirCheck = new bool[8];
                dirCheck[0] = CopyFileSet.IsEverythingIncluded;
                dirCheck[1] = !Flatten;
                dirCheck[2] = IncludeEmptyDirs || !CopyFileSet.HasEmptyDirectories;
                dirCheck[3] = FilterChain.IsNullOrEmpty(Filters);
                dirCheck[4] = _inputEncoding == null;
                dirCheck[5] = _outputEncoding == null;
                dirCheck[6] = srcBaseInfo != null && srcBaseInfo.Exists;
                dirCheck[7] = !ToDirectory.Exists ||
                              srcBaseInfo.FullName.Equals(ToDirectory.FullName,
                                                          StringComparison.InvariantCultureIgnoreCase);

                for (int b = 0; b < dirCheck.Length; b++)
                {
                    completeDir &= dirCheck[b];
                }

                if (completeDir)
                {
                    FileCopyMap.Add(ToDirectory.FullName,
                                    new FileDateInfo(srcBaseInfo.FullName, srcBaseInfo.LastWriteTime, true));
                    _dirCount++;
                }
                else
                {
                    // if source file not specified use fileset
                    foreach (string pathname in CopyFileSet.FileNames)
                    {
                        FileInfo srcInfo = new FileInfo(pathname);
                        if (srcInfo.Exists)
                        {
                            // will holds the full path to the destination file
                            string dstFilePath;

                            if (Flatten)
                            {
                                dstFilePath = Path.Combine(ToDirectory.FullName,
                                                           srcInfo.Name);
                            }
                            else
                            {
                                // Gets the relative path and file info from the full
                                // source filepath
                                // pathname = C:\f2\f3\file1, srcBaseInfo=C:\f2, then
                                // dstRelFilePath=f3\file1
                                string dstRelFilePath = "";
                                if (srcInfo.FullName.IndexOf(srcBaseInfo.FullName, 0) != -1)
                                {
                                    dstRelFilePath = srcInfo.FullName.Substring(
                                        srcBaseInfo.FullName.Length);
                                }
                                else
                                {
                                    dstRelFilePath = srcInfo.Name;
                                }

                                if (dstRelFilePath[0] == Path.DirectorySeparatorChar)
                                {
                                    dstRelFilePath = dstRelFilePath.Substring(1);
                                }

                                // The full filepath to copy to.
                                dstFilePath = Path.Combine(ToDirectory.FullName,
                                                           dstRelFilePath);
                            }

                            // do the outdated check
                            FileInfo dstInfo  = new FileInfo(dstFilePath);
                            bool     outdated = (!dstInfo.Exists) || (srcInfo.LastWriteTime > dstInfo.LastWriteTime);

                            if (Overwrite || outdated)
                            {
                                // construct FileDateInfo for current file
                                FileDateInfo newFile = new FileDateInfo(srcInfo.FullName,
                                                                        srcInfo.LastWriteTime);
                                // if multiple source files are selected to be copied
                                // to the same destination file, then only the last
                                // updated source should actually be copied
                                FileDateInfo oldFile = (FileDateInfo)FileCopyMap[dstInfo.FullName];
                                if (oldFile != null)
                                {
                                    // if current file was updated after scheduled file,
                                    // then replace it
                                    if (newFile.LastWriteTime > oldFile.LastWriteTime)
                                    {
                                        FileCopyMap[dstInfo.FullName] = newFile;
                                    }
                                }
                                else
                                {
                                    FileCopyMap.Add(dstInfo.FullName, newFile);
                                    _fileCount++;

                                    if (dstInfo.Exists && dstInfo.Attributes != FileAttributes.Normal)
                                    {
                                        File.SetAttributes(dstInfo.FullName, FileAttributes.Normal);
                                    }
                                }
                            }
                        }
                        else
                        {
                            throw CreateSourceFileNotFoundException(srcInfo.FullName);
                        }
                    }

                    if (IncludeEmptyDirs && !Flatten)
                    {
                        // create any specified directories that weren't created during the copy (ie: empty directories)
                        foreach (string pathname in CopyFileSet.DirectoryNames)
                        {
                            DirectoryInfo srcInfo = new DirectoryInfo(pathname);
                            // skip directory if not relative to base dir of fileset
                            if (srcInfo.FullName.IndexOf(srcBaseInfo.FullName) == -1)
                            {
                                continue;
                            }
                            string dstRelPath = srcInfo.FullName.Substring(srcBaseInfo.FullName.Length);
                            if (dstRelPath.Length > 0 && dstRelPath[0] == Path.DirectorySeparatorChar)
                            {
                                dstRelPath = dstRelPath.Substring(1);
                            }

                            // The full filepath to copy to.
                            string destinationDirectory = Path.Combine(ToDirectory.FullName, dstRelPath);
                            if (!Directory.Exists(destinationDirectory))
                            {
                                try {
                                    Directory.CreateDirectory(destinationDirectory);
                                } catch (Exception ex) {
                                    throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                                           "Failed to create directory '{0}'.", destinationDirectory),
                                                             Location, ex);
                                }
                                Log(Level.Verbose, "Created directory '{0}'.", destinationDirectory);
                            }
                        }
                    }
                }
            }

            // do all the actual copy operations now
            DoFileOperations();
        }
Exemplo n.º 3
0
        /// <summary>
        /// Copies a file filtering its content through the filter chain.
        /// </summary>
        /// <param name="sourceFileName">
        /// The file to copy
        /// </param>
        /// <param name="destFileName">
        /// The file to copy to
        /// </param>
        /// <param name="filterChain">
        /// Chain of filters to apply when copying, or <see langword="null" /> is no
        /// filters should be applied.
        /// </param>
        /// <param name="inputEncoding">
        /// The encoding used to read the soure file.
        /// </param>
        /// <param name="outputEncoding">
        /// The encoding used to write the destination file.
        /// </param>
        public static void CopyFile(
            string sourceFileName,
            string destFileName,
            FilterChain filterChain,
            Encoding inputEncoding,
            Encoding outputEncoding)
        {
            // If the source file does not exist, throw an exception.
            if (!File.Exists(sourceFileName))
            {
                throw new BuildException(
                          String.Format("Cannot copy file: Source File {0} does not exist",
                                        sourceFileName));
            }

            // determine if filters are available
            bool filtersAvailable = !FilterChain.IsNullOrEmpty(filterChain);

            // if no filters have been defined, and no input or output encoding
            // is set, we can just use the File.Copy method
            if (!filtersAvailable && inputEncoding == null && outputEncoding == null)
            {
                File.Copy(sourceFileName, destFileName, true);
            }
            else
            {
                // determine actual input encoding to use. if no explicit input
                // encoding is specified, we'll use the system's current ANSI
                // code page
                Encoding actualInputEncoding = (inputEncoding != null) ?
                                               inputEncoding : Encoding.Default;

                // get base filter built on the file's reader.
                // Use the value of _bufferSize as the buffer size.
                using (StreamReader sourceFileReader =
                           new StreamReader(sourceFileName, actualInputEncoding, true, _bufferSize))
                {
                    Encoding actualOutputEncoding = outputEncoding;
                    if (actualOutputEncoding == null)
                    {
                        // if no explicit output encoding is specified, we'll
                        // just use the encoding of the input file as determined
                        // by the runtime
                        //
                        // Note : the input encoding as specified on the filterchain
                        // might not match the current encoding of the streamreader
                        //
                        // eg. when specifing an ANSI encoding, the runtime might
                        // still detect the file is using UTF-8 encoding, because
                        // we use BOM detection
                        actualOutputEncoding = sourceFileReader.CurrentEncoding;
                    }

                    // writer for destination file
                    using (StreamWriter destFileWriter =
                               new StreamWriter(destFileName, false, actualOutputEncoding, _bufferSize))
                    {
                        if (filtersAvailable)
                        {
                            Filter baseFilter =
                                filterChain.GetBaseFilter(new PhysicalTextReader(sourceFileReader));

                            bool atEnd = false;
                            int  character;
                            while (!atEnd)
                            {
                                character = baseFilter.Read();
                                if (character > -1)
                                {
                                    destFileWriter.Write((char)character);
                                }
                                else
                                {
                                    atEnd = true;
                                }
                            }
                        }
                        else
                        {
                            char[] buffer = new char[_bufferSize];

                            while (true)
                            {
                                int charsRead = sourceFileReader.Read(buffer, 0, buffer.Length);
                                if (charsRead == 0)
                                {
                                    break;
                                }
                                destFileWriter.Write(buffer, 0, charsRead);
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Moves a directory while filtering its file content through the filter chain.
        /// </summary>
        /// <param name="sourceDirectory">
        /// Source directory to move from.
        /// </param>
        /// <param name="destDirectory">
        /// Destination directory to move to.
        /// </param>
        /// <param name="filterChain">
        /// Chain of filters to apply when copying, or <see langword="null" /> is no
        /// filters should be applied.
        /// </param>
        /// <param name="inputEncoding">
        /// The encoding used to read the soure file.
        /// </param>
        /// <param name="outputEncoding">
        /// The encoding used to write the destination file.
        /// </param>
        internal static void MoveDirectory(
            string sourceDirectory,
            string destDirectory,
            FilterChain filterChain,
            Encoding inputEncoding,
            Encoding outputEncoding)
        {
            // If the source directory does not exist, throw an exception.
            if (!Directory.Exists(sourceDirectory))
            {
                throw new BuildException(
                          String.Format("Cannot move directory: Source Directory {0} does not exist",
                                        sourceDirectory));
            }

            // if no filters have been defined, and no input or output encoding
            // is set, proceed with a straight directory move.
            if (FilterChain.IsNullOrEmpty(filterChain) &&
                inputEncoding == null &&
                outputEncoding == null)
            {
                // If the source & target paths are completely the same, including
                // case, throw an exception.
                if (sourceDirectory.Equals(destDirectory, StringComparison.InvariantCulture))
                {
                    throw new BuildException("Source and Target paths are identical");
                }

                try
                {
                    // wants to rename a directory with the same name but different casing
                    // (ie: C:\nant to C:\NAnt), then the move needs to be staged.
                    if (PlatformHelper.IsWindows)
                    {
                        // If the directory names are the same but different casing, stage
                        // the move by moving the source directory to a temp location
                        // before moving it to the destination.
                        if (sourceDirectory.Equals(destDirectory,
                                                   StringComparison.InvariantCultureIgnoreCase))
                        {
                            // Since the directory is being renamed with different
                            // casing, the temp directory should be in the same
                            // location as the destination directory to avoid
                            // possible different volume errors.
                            string rootPath  = Directory.GetParent(destDirectory).FullName;
                            string stagePath =
                                Path.Combine(rootPath, Path.GetRandomFileName());

                            try
                            {
                                // Move the source dir to the stage path
                                // before moving everything to the destination
                                // path.
                                Directory.Move(sourceDirectory, stagePath);
                                Directory.Move(stagePath, destDirectory);
                            }
                            catch
                            {
                                // If an error occurred during the staged directory
                                // move, check to see if the stage path exists.  If
                                // the source directory successfully moved to the
                                // stage path, move the stage path back to the
                                // source path and rethrow the exception.
                                if (Directory.Exists(stagePath))
                                {
                                    if (!Directory.Exists(sourceDirectory))
                                    {
                                        Directory.Move(stagePath, sourceDirectory);
                                    }
                                }
                                throw;
                            }
                        }
                        // If the directory source and destination names are
                        // different, use Directory.Move.
                        else
                        {
                            Directory.Move(sourceDirectory, destDirectory);
                        }
                    }

                    // Non-Windows systems, such as Linux/Unix, filenames and directories
                    // are case-sensitive. So as long as the directory names are not
                    // identical, with the check above, the Directory.Move method
                    // can be used.
                    else
                    {
                        Directory.Move(sourceDirectory, destDirectory);
                    }
                }
                // Catch and rethrow any IO exceptions that may arise during
                // the directory move.
                catch (IOException ioEx)
                {
                    // If the error occurred because the destination directory
                    // exists, throw a build exception to tell the user that the
                    // destination directory already exists.
                    if (Directory.Exists(destDirectory))
                    {
                        throw new BuildException(
                                  string.Format(CultureInfo.InvariantCulture,
                                                "Failed to move directory {0}." +
                                                "Directory '{1}' already exists.",
                                                sourceDirectory, destDirectory));
                    }
                    // Any other IOExceptions should be displayed to the user
                    // via build exception.
                    else
                    {
                        throw new BuildException(
                                  String.Format("Unhandled IOException when trying to move directory '{0}' to '{1}'",
                                                sourceDirectory, destDirectory), ioEx);
                    }
                }
            }
            else
            {
                // Otherwise, use the copy directory method and directory.delete
                // method to move the directory over.
                CopyDirectory(sourceDirectory, destDirectory, filterChain,
                              inputEncoding, outputEncoding);
                Directory.Delete(sourceDirectory, true);
            }
        }