public async static Task <String> ReadFile(File file) { using (AtomicFile mFile = new AtomicFile(file)) { // Wait for file to be free while (IsFileLocked(file)) { await Task.Delay(100); } String data; using (BufferedReader reader = new BufferedReader(new InputStreamReader(mFile.OpenRead()))) { String line = await reader.ReadLineAsync(); StringBuilder sBuilder = new StringBuilder(); while (line != null) { sBuilder.Append(line).Append("\n"); line = await reader.ReadLineAsync(); } reader.Dispose(); data = sBuilder.ToString(); } return(data); } }
public void CanWrite() { using (var container = TemporaryDirectory.CreateNew()) { var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); sut.Write(42); } }
public void CanDeleteWrittenValue() { using (var container = TemporaryDirectory.CreateNew()) { var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); sut.Write(42); sut.Delete(); Assert.That(sut.Read(), Is.EqualTo(default(int))); } }
public void CanReplaceWrittenValue() { using (var container = TemporaryDirectory.CreateNew()) { var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); sut.Write(42); sut.Write(23); var value = sut.Read(); Assert.That(value, Is.EqualTo(23)); } }
public void FailedWriteDoesNotOverwriteExistingValue() { using (var container = TemporaryDirectory.CreateNew()) { var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); sut.Write(42); Assume.That(sut.Read(), Is.EqualTo(42)); var failing = new AtomicFile <int>(container.File("key-path"), new RandomlyFailingSerialiser <int>(new StubSerialiser(), 1)); Assume.That(() => failing.Write(23), Throws.InstanceOf <IOException>()); Assert.That(sut.Read(), Is.EqualTo(42)); } }
/// <summary> /// Enumerate all derived mods from a list of mods /// </summary> /// <param name="ModList"></param> private void EnumerateMods() { DirectoryInfo location = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); HashSet <string> suppress = AtomicFile.ReadStream(Path.Combine(location.FullName, "loader.suppress"), false).ReadAllText().Split('\n', '\r', ' ', '\t') .ToSet(); suppress.RemoveAll((string x) => x.Trim().Length == 0); List <Type> ModList = new List <Type>(); foreach (FileInfo AssemblyDll in location.GetFiles("*.dll").Concat(location.GetFiles("*.exe"))) { HashSet <string> source = suppress; Func <string, bool> predicate = (string suppression) => AssemblyDll.FullName.IndexOf(suppression, StringComparison.OrdinalIgnoreCase) != -1; if (!source.Any(predicate) && File.Exists(Path.ChangeExtension(AssemblyDll.FullName, ".mod"))) { try { foreach (Type AssemblyType in Assembly.LoadFrom(AssemblyDll.FullName).GetTypes()) { if (!AssemblyType.IsAbstract && AssemblyType.IsClass && typeof(SunbeamMod).IsAssignableFrom(AssemblyType)) { ModList.Add(AssemblyType); } } } catch (ReflectionTypeLoadException e) {} } } Logger.WriteLine("SunbeamController.EnumerateMods: Found " + ModList.Count + " mods."); foreach (Type ModType in ModList) { try { SunbeamMod Mod = (SunbeamMod)Activator.CreateInstance(ModType); Mod.ApplyHarmonyPatches(); Mod.Initialize(); Logger.WriteLine("SunbeamController.EnumerateMods: Loaded mod '" + Mod.ModIdentifier + "'"); this.Mods.Add(Mod); } catch (Exception e) { Logger.WriteLine("SunbeamController.EnumerateMods: Exception thrown - " + e.ToString()); } } }
public async Task FuzzConcurrentAccess() { const int threadCount = 5; const int iterationCountPerThread = 25; var writtenValues = new List <int>(); var random = new Random(); var failures = new List <Exception>(); using (var container = TemporaryDirectory.CreateNew()) { var path = container.File("key-path"); await ConcurrentOperations.Run(threadCount, () => { var sut = new AtomicFile <int>(path, new RandomlyFailingSerialiser <int>(new StubSerialiser(), 0.05)); for (var i = 0; i < iterationCountPerThread; i++) { try { var value = random.Next(100); sut.Write(value); lock (writtenValues) writtenValues.Add(value); } catch (FileLockedException) { // We expect locking conflicts to represent the bulk of failures. } catch (Exception ex) { lock (failures) failures.Add(ex); } try { sut.Read(); } catch (Exception) { } } }); var finalValue = new AtomicFile <int>(path, new StubSerialiser()).Read(); // At least one write should succeed. Assume.That(writtenValues.Count, Is.GreaterThan(1)); // Due to races it's not guaranteed that the last entry in the list is the last one successfully written. // However, this should be vanishingly unlikely because it would require that another Write call ran to // completion between `sut.Write(value);` and `lock (writtenValues)`. Assert.That(finalValue, Is.EqualTo(writtenValues.Last())); } }
public void CanAccessViaMultipleInstances() { using (var container = TemporaryDirectory.CreateNew()) { var sut1 = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); var sut2 = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); var sut3 = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); sut1.Write(42); sut2.Write(17); sut3.Write(23); var value = sut2.Read(); Assert.That(value, Is.EqualTo(23)); } }
public static Task <T> DeserializerAsync <T>(Java.IO.File file) #endif { return(Task.Run(async() => { // Wait for file to be free while (FileUtils.IsFileLocked(file)) { await Task.Delay(100).ConfigureAwait(false); } Stream fStream = null; StreamReader sReader = null; JsonReader reader = null; var obj = default(T); #if __ANDROID__ var mFile = new AtomicFile(file); try { fStream = mFile.OpenRead(); #else try { fStream = new FileStream(file.Path, FileMode.Open, FileAccess.Read); #endif sReader = new StreamReader(fStream); reader = new JsonTextReader(sReader); var serializer = JsonSerializer.Create(DefaultSettings); obj = serializer.Deserialize <T>(reader); } catch (Exception ex) { Logger.WriteLine(LoggerLevel.Error, ex, "SimpleWeather: JSONParser: error deserializing or with file"); obj = default(T); } finally { reader?.Close(); #if __ANDROID__ mFile?.Dispose(); #endif } return obj; })); }
public static void Serializer(Object obj, Java.IO.File file) { Task.Run(async() => { // Wait for file to be free while (FileUtils.IsFileLocked(file)) { await Task.Delay(100).ConfigureAwait(false); } var mFile = new AtomicFile(file); Stream fStream = null; JsonTextWriter writer = null; try { fStream = mFile.StartWrite(); writer = new JsonTextWriter(new StreamWriter(fStream)) { CloseOutput = false, }; var serializer = JsonSerializer.Create(DefaultSettings); serializer.Serialize(writer, obj); await writer.FlushAsync().ConfigureAwait(false); mFile.FinishWrite(fStream); } catch (Exception ex) { Logger.WriteLine(LoggerLevel.Error, ex, "SimpleWeather: JSONParser: error serializing or with file"); if (mFile != null && fStream != null) { mFile.FailWrite(fStream); } } finally { mFile?.Dispose(); writer?.Close(); } }).ConfigureAwait(false); }
public static async Task WriteFile(String data, File file) { using (AtomicFile mFile = new AtomicFile(file)) { // Wait for file to be free while (IsFileLocked(file)) { await Task.Delay(100); } using (System.IO.Stream outputStream = mFile.StartWrite()) using (System.IO.StreamWriter writer = new System.IO.StreamWriter(outputStream)) { // Clear file before writing outputStream.SetLength(0); await writer.WriteAsync(data); await writer.FlushAsync(); mFile.FinishWrite(outputStream); } } }
/// <summary> /// Retrieve a file's content as text from the mod directory /// </summary> /// <param name="assetPath"></param> /// <returns></returns> public string ReadFileContent(string assetPath) { assetPath = Path.GetFullPath(Path.Combine(this.ModDirectory, assetPath)); return(AtomicFile.ReadText(assetPath, true)); }