A game framework written with osu! in mind.
at master 133 lines 5.6 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using System.Collections.Generic; 6using System.IO; 7 8namespace osu.Framework.Platform 9{ 10 public abstract class Storage 11 { 12 protected string BasePath { get; } 13 14 protected Storage(string path, string subfolder = null) 15 { 16 static string filenameStrip(string entry) 17 { 18 foreach (char c in Path.GetInvalidFileNameChars()) 19 entry = entry.Replace(c.ToString(), string.Empty); 20 return entry; 21 } 22 23 BasePath = path; 24 25 if (BasePath == null) 26 throw new InvalidOperationException($"{nameof(BasePath)} not correctly initialized!"); 27 28 if (!string.IsNullOrEmpty(subfolder)) 29 BasePath = Path.Combine(BasePath, filenameStrip(subfolder)); 30 } 31 32 /// <summary> 33 /// Get a usable filesystem path for the provided incomplete path. 34 /// </summary> 35 /// <param name="path">An incomplete path, usually provided as user input.</param> 36 /// <param name="createIfNotExisting">Create the path if it doesn't already exist.</param> 37 /// <returns>A usable filesystem path.</returns> 38 public abstract string GetFullPath(string path, bool createIfNotExisting = false); 39 40 /// <summary> 41 /// Check whether a file exists at the specified path. 42 /// </summary> 43 /// <param name="path">The path to check.</param> 44 /// <returns>Whether a file exists.</returns> 45 public abstract bool Exists(string path); 46 47 /// <summary> 48 /// Check whether a directory exists at the specified path. 49 /// </summary> 50 /// <param name="path">The path to check.</param> 51 /// <returns>Whether a directory exists.</returns> 52 public abstract bool ExistsDirectory(string path); 53 54 /// <summary> 55 /// Delete a directory and all its contents recursively. 56 /// </summary> 57 /// <param name="path">The path of the directory to delete.</param> 58 public abstract void DeleteDirectory(string path); 59 60 /// <summary> 61 /// Delete a file. 62 /// </summary> 63 /// <param name="path">The path of the file to delete.</param> 64 public abstract void Delete(string path); 65 66 /// <summary> 67 /// Retrieve a list of directories at the specified path. 68 /// </summary> 69 /// <param name="path">The path to list.</param> 70 /// <returns>A list of directories in the path, relative to the path of this storage.</returns> 71 public abstract IEnumerable<string> GetDirectories(string path); 72 73 /// <summary> 74 /// Retrieve a list of files at the specified path. 75 /// </summary> 76 /// <param name="path">The path to list.</param> 77 /// <param name="pattern">An optional search pattern. Accepts "*" wildcard.</param> 78 /// <returns>A list of files in the path, relative to the path of this storage.</returns> 79 public abstract IEnumerable<string> GetFiles(string path, string pattern = "*"); 80 81 /// <summary> 82 /// Retrieve a <see cref="Storage"/> for a contained directory. 83 /// Creates the path if not existing. 84 /// </summary> 85 /// <param name="path">The subdirectory to use as a root.</param> 86 /// <returns>A more specific storage.</returns> 87 public virtual Storage GetStorageForDirectory(string path) 88 { 89 if (string.IsNullOrEmpty(path)) 90 throw new ArgumentException("Must be non-null and not empty string", nameof(path)); 91 92 if (!path.EndsWith(Path.DirectorySeparatorChar)) 93 path += Path.DirectorySeparatorChar; 94 95 // create non-existing path. 96 var fullPath = GetFullPath(path, true); 97 98 return (Storage)Activator.CreateInstance(GetType(), fullPath); 99 } 100 101 /// <summary> 102 /// Retrieve a stream from an underlying file inside this storage. 103 /// </summary> 104 /// <param name="path">The path of the file.</param> 105 /// <param name="access">The access requirements.</param> 106 /// <param name="mode">The mode in which the file should be opened.</param> 107 /// <returns>A stream associated with the requested path.</returns> 108 public abstract Stream GetStream(string path, FileAccess access = FileAccess.Read, FileMode mode = FileMode.OpenOrCreate); 109 110 /// <summary> 111 /// Retrieve an SQLite database connection string from within this storage. 112 /// </summary> 113 /// <param name="name">The name of the database.</param> 114 /// <returns>An SQLite connection string.</returns> 115 public abstract string GetDatabaseConnectionString(string name); 116 117 /// <summary> 118 /// Delete an SQLite database from within this storage. 119 /// </summary> 120 /// <param name="name">The name of the database to delete.</param> 121 public abstract void DeleteDatabase(string name); 122 123 /// <summary> 124 /// Opens a native file browser window to the root path of this storage. 125 /// </summary> 126 public void OpenInNativeExplorer() => OpenPathInNativeExplorer(string.Empty); 127 128 /// <summary> 129 /// Opens a native file browser window to the specified relative path. 130 /// </summary> 131 public abstract void OpenPathInNativeExplorer(string path); 132 } 133}