Example #1
0
        /// <summary>
        /// Copies an existing file to a new file, allowing overwriting of an existing file.
        /// </summary>
        /// <param name="sourceFile">The source file</param>
        /// <param name="destinationFile">The destination file</param>
        /// <param name="overwrite">Whether to permit over-writing of an existing file.</param>
        public override void CopyFile(string sourceFile, string destinationFile, bool overwrite)
        {
            Directory sourceDir;
            long sourceEntryId = GetDirectoryEntry(sourceFile, out sourceDir);

            if (sourceDir == null || sourceEntryId < 0)
            {
                throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "The source file '{0}' was not found", sourceFile));
            }

            DirectoryEntry sourceEntry = sourceDir.GetEntry(sourceEntryId);

            if ((sourceEntry.Attributes & FatAttributes.Directory) != 0)
            {
                throw new IOException("The source file is a directory");
            }

            DirectoryEntry newEntry = new DirectoryEntry(sourceEntry);
            newEntry.Name = FileName.FromPath(destinationFile, FatOptions.FileNameEncoding);
            newEntry.FirstCluster = 0;

            Directory destDir;
            long destEntryId = GetDirectoryEntry(destinationFile, out destDir);

            if (destDir == null)
            {
                throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, "The destination directory for '{0}' was not found", destinationFile));
            }

            // If the destination is a directory, use the old file name to construct a full path.
            if (destEntryId >= 0)
            {
                DirectoryEntry destEntry = destDir.GetEntry(destEntryId);
                if ((destEntry.Attributes & FatAttributes.Directory) != 0)
                {
                    newEntry.Name = FileName.FromPath(sourceFile, FatOptions.FileNameEncoding);
                    destinationFile = Utilities.CombinePaths(destinationFile, Utilities.GetFileFromPath(sourceFile));

                    destEntryId = GetDirectoryEntry(destinationFile, out destDir);
                }
            }

            // If there's an existing entry...
            if (destEntryId >= 0)
            {
                DirectoryEntry destEntry = destDir.GetEntry(destEntryId);

                if ((destEntry.Attributes & FatAttributes.Directory) != 0)
                {
                    throw new IOException("Destination file is an existing directory");
                }

                if (!overwrite)
                {
                    throw new IOException("Destination file already exists");
                }

                // Remove the old file
                destDir.DeleteEntry(destEntryId, true);
            }

            // Add the new file's entry
            destEntryId = destDir.AddEntry(newEntry);

            // Copy the contents...
            using (Stream sourceStream = new FatFileStream(this, sourceDir, sourceEntryId, FileAccess.Read),
                destStream = new FatFileStream(this, destDir, destEntryId, FileAccess.Write))
            {
                Utilities.PumpStreams(sourceStream, destStream);
            }
        }
Example #2
0
        internal SparseStream OpenFile(FileName name, FileMode mode, FileAccess fileAccess)
        {
            if (mode == FileMode.Append || mode == FileMode.Truncate)
            {
                throw new NotImplementedException();
            }

            long fileId = FindEntry(name);
            bool exists = fileId != -1;

            if (mode == FileMode.CreateNew && exists)
            {
                throw new IOException("File already exists");
            }
            else if (mode == FileMode.Open && !exists)
            {
                throw new FileNotFoundException("File not found", name.GetDisplayName(_fileSystem.FatOptions.FileNameEncoding));
            }
            else if ((mode == FileMode.Open || mode == FileMode.OpenOrCreate || mode == FileMode.Create) && exists)
            {
                SparseStream stream = new FatFileStream(_fileSystem, this, fileId, fileAccess);
                if (mode == FileMode.Create)
                {
                    stream.SetLength(0);
                }

                HandleAccessed(false);

                return stream;
            }
            else if ((mode == FileMode.OpenOrCreate || mode == FileMode.CreateNew || mode == FileMode.Create) && !exists)
            {
                // Create new file
                DirectoryEntry newEntry = new DirectoryEntry(_fileSystem.FatOptions, name, FatAttributes.Archive);
                newEntry.FirstCluster = 0; // i.e. Zero-length
                newEntry.CreationTime = _fileSystem.ConvertFromUtc(DateTime.UtcNow);
                newEntry.LastWriteTime = newEntry.CreationTime;

                fileId = AddEntry(newEntry);

                return new FatFileStream(_fileSystem, this, fileId, fileAccess);
            }
            else
            {
                // Should never get here...
                throw new NotImplementedException();
            }
        }