Пример #1
0
 /// <summary>
 /// Deletes the file that is referred to by the specified path.
 /// </summary>
 /// <param name="path"></param>
 public static void Delete(string path)
 {
     if (string.IsNullOrWhiteSpace(path))
     {
         return;
     }
     PathOp.CheckInvalidPathChars(path);
     DualityApp.SystemBackend.FileSystem.DeleteFile(path);
 }
Пример #2
0
 /// <summary>
 /// Returns whether the specified path refers to an existing file.
 /// </summary>
 /// <param name="path"></param>
 /// <returns></returns>
 public static bool Exists(string path)
 {
     if (string.IsNullOrWhiteSpace(path))
     {
         return(false);
     }
     PathOp.CheckInvalidPathChars(path);
     return(DualityApp.SystemBackend.FileSystem.FileExists(path));
 }
Пример #3
0
 /// <summary>
 /// Opens an existing file at the specified path and returns a <see cref="System.IO.Stream"/> to it.
 /// </summary>
 /// <param name="path"></param>
 /// <param name="mode"></param>
 public static Stream Open(string path, FileAccessMode mode)
 {
     if (string.IsNullOrWhiteSpace(path))
     {
         throw new ArgumentException("The specified path is null or whitespace-only.");
     }
     PathOp.CheckInvalidPathChars(path);
     return(DualityApp.SystemBackend.FileSystem.OpenFile(path, mode));
 }
Пример #4
0
 /// <summary>
 /// Creates a directory tree matching the specified directory path.
 /// </summary>
 /// <param name="path"></param>
 public static void Create(string path)
 {
     if (string.IsNullOrWhiteSpace(path))
     {
         throw new ArgumentException("The specified path is null or whitespace-only.");
     }
     PathOp.CheckInvalidPathChars(path);
     DualityApp.SystemBackend.FileSystem.CreateDirectory(path);
 }
Пример #5
0
 /// <summary>
 /// Enumerates all directories that are located within the specified path.
 /// </summary>
 /// <param name="path"></param>
 /// <param name="recursive">If true, the specified path will be searched recursively and yield all descendant directory paths.</param>
 /// <returns></returns>
 public static IEnumerable <string> GetDirectories(string path, bool recursive = false)
 {
     if (string.IsNullOrWhiteSpace(path))
     {
         return(Enumerable.Empty <string>());
     }
     PathOp.CheckInvalidPathChars(path);
     return(DualityApp.SystemBackend.FileSystem.GetDirectories(path, recursive));
 }
Пример #6
0
 /// <summary>
 /// Deletes the directory that is referred to by the specified path.
 /// </summary>
 /// <param name="path"></param>
 public static void Delete(string path)
 {
     if (string.IsNullOrWhiteSpace(path))
     {
         return;
     }
     PathOp.CheckInvalidPathChars(path);
     PathOp.ResolveFileSystem(ref path).DeleteDirectory(path);
 }
Пример #7
0
 /// <summary>
 /// Returns whether the specified path refers to an existing directory.
 /// </summary>
 /// <param name="path"></param>
 /// <returns></returns>
 public static bool Exists(string path)
 {
     if (string.IsNullOrWhiteSpace(path))
     {
         return(false);
     }
     PathOp.CheckInvalidPathChars(path);
     return(PathOp.ResolveFileSystem(ref path).DirectoryExists(path));
 }
Пример #8
0
 /// <summary>
 /// Creates or overwrites a file at the specified path and returns a <see cref="System.IO.Stream"/> to it.
 /// The returned stream has implicit read / write access.
 /// </summary>
 /// <param name="path"></param>
 public static Stream Create(string path)
 {
     if (string.IsNullOrWhiteSpace(path))
     {
         throw new ArgumentException("The specified path is null or whitespace-only.");
     }
     PathOp.CheckInvalidPathChars(path);
     return(PathOp.ResolveFileSystem(ref path).CreateFile(path));
 }
Пример #9
0
 public int GetHashCode(string obj)
 {
     if (string.IsNullOrWhiteSpace(obj))
     {
         return(0);
     }
     else
     {
         return(PathOp.GetFullPath(obj).GetHashCode());
     }
 }
Пример #10
0
        /// <summary>
        /// Enumerates all directories that are located within the specified path.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="recursive">If true, the specified path will be searched recursively and yield all descendant directory paths.</param>
        /// <returns></returns>
        public static IEnumerable <string> GetDirectories(string path, bool recursive = false)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                return(Enumerable.Empty <string>());
            }
            PathOp.CheckInvalidPathChars(path);

            int index = PathOp.IndexOfFileSystem(path);

            if (index == -1)
            {
                return(DualityApp.SystemBackend.FileSystem.GetDirectories(path, recursive));
            }
            else
            {
                return(PathOp.PrepareFileSystemForEnumerationUnsafe(index, true, path, recursive));
            }
        }
Пример #11
0
 public bool Equals(string x, string y)
 {
     return(PathOp.ArePathsEqual(x, y));
 }
Пример #12
0
        /// <summary>
        /// Performs an aggregate operation on all new events, starting at the specified index.
        /// Each event will include all previous events in its aggregate check.
        /// </summary>
        /// <param name="addedStartingIndex"></param>
        private void AggregateNewlyAdded(int addedStartingIndex)
        {
            // Iterate backwards over newly added events, and run an aggregation step
            // with all previous events for each of them.
            for (int currentIndex = this.items.Count - 1; currentIndex >= addedStartingIndex; currentIndex--)
            {
                FileEvent current            = this.items[currentIndex];
                string    currentOldFileName = PathOp.GetFileName(current.OldPath);
                string    currentFileName    = PathOp.GetFileName(current.Path);
                bool      discardedCurrent   = false;

                // Aggregate with previous events, so the latest event
                // in an aggregate chain is the one that defines event order.
                for (int prevIndex = currentIndex - 1; prevIndex >= 0; prevIndex--)
                {
                    FileEvent prev         = this.items[prevIndex];
                    string    prevFileName = PathOp.GetFileName(prev.Path);
                    bool      consumedPrev = false;

                    // Aggregate identical events
                    if (current.Equals(prev))
                    {
                        consumedPrev = true;
                    }
                    // Aggregate "delete Foo/A, create Bar/A" to "rename Foo/A to Bar/A" events.
                    // Aggregate "delete Foo/A, create Foo/A" to "change Foo/A" events.
                    else if (
                        current.Type == FileEventType.Created &&
                        prev.Type == FileEventType.Deleted &&
                        currentFileName == prevFileName)
                    {
                        current.Type = (current.Path == prev.Path) ?
                                       FileEventType.Changed :
                                       FileEventType.Renamed;
                        current.OldPath = prev.Path;
                        consumedPrev    = true;
                    }
                    // Aggregate sequential renames / moves of the same file
                    else if (
                        current.Type == FileEventType.Renamed &&
                        prev.Type == FileEventType.Renamed &&
                        currentOldFileName == prevFileName)
                    {
                        current.OldPath = prev.OldPath;
                        consumedPrev    = true;
                    }
                    // Aggregate "delete A, then rename B to A" into "delete B, changed A" events.
                    // Some applications (like Photoshop) do stuff like that when saving files.
                    else if (
                        current.Type == FileEventType.Renamed &&
                        prev.Type == FileEventType.Deleted &&
                        current.Path == prev.Path)
                    {
                        FileEvent deleted = current;
                        deleted.Type    = FileEventType.Deleted;
                        deleted.Path    = current.OldPath;
                        deleted.OldPath = current.OldPath;
                        this.items.Insert(currentIndex, deleted);
                        currentIndex++;

                        current.Type    = FileEventType.Changed;
                        current.OldPath = current.Path;
                        consumedPrev    = true;
                    }
                    // Aggregate anything before a delete into just the delete
                    else if (
                        current.Type == FileEventType.Deleted &&
                        prev.Path == current.Path)
                    {
                        // Special case for previous renames: Translate the delete back to the old path
                        if (prev.Type == FileEventType.Renamed)
                        {
                            current.Path    = prev.OldPath;
                            current.OldPath = prev.OldPath;
                        }
                        // Special case for previous creates: Discard both the delete and the create.
                        else if (prev.Type == FileEventType.Created)
                        {
                            discardedCurrent = true;
                        }
                        consumedPrev = true;
                    }
                    // Aggregate anything after a create into just the create
                    else if (
                        prev.Type == FileEventType.Created &&
                        (prev.Path == current.Path || prev.Path == current.OldPath))
                    {
                        current.Type    = FileEventType.Created;
                        current.OldPath = current.Path;
                        consumedPrev    = true;
                    }

                    // Remove the previous item if it was aggregated with the current
                    if (consumedPrev)
                    {
                        this.items.RemoveAt(prevIndex);

                        // Update other indices to account for removed item
                        currentIndex--;
                        if (addedStartingIndex > prevIndex)
                        {
                            addedStartingIndex--;
                        }
                    }
                }

                // Filter out no-op events
                if (current.Type == FileEventType.Renamed &&
                    current.OldPath == current.Path)
                {
                    discardedCurrent = true;
                }

                // Discard or update the current event
                if (discardedCurrent)
                {
                    this.items.RemoveAt(currentIndex);
                }
                else
                {
                    this.items[currentIndex] = current;
                }
            }
        }