internal async ReusableTask <RentedStream> GetStreamAsync(ITorrentFileInfo file, FileAccess access) { if (!Streams.TryGetValue(file, out ITorrentFileStream s)) { s = null; } if (s != null) { // If we are requesting write access and the current stream does not have it if (((access & FileAccess.Write) == FileAccess.Write) && !s.CanWrite) { logger.InfoFormatted("Didn't have write permission for {0} - reopening", file.Path); CloseAndRemove(file, s); s = null; } else { // Place the filestream at the end so we know it's been recently used Streams.Remove(file); Streams.Add(file, s); } } if (s == null) { if (!File.Exists(file.FullPath)) { if (!string.IsNullOrEmpty(Path.GetDirectoryName(file.FullPath))) { Directory.CreateDirectory(Path.GetDirectoryName(file.FullPath)); } NtfsSparseFile.CreateSparse(file.FullPath, file.Length); } s = StreamCreator(file, access); // Ensure that we truncate existing files which are too large if (s.Length > file.Length) { if (!s.CanWrite) { s.Dispose(); s = StreamCreator(file, FileAccess.ReadWrite); } await s.SetLengthAsync(file.Length); } Add(file, s); } return(new RentedStream(s)); }
internal async ReusableTask <RentedStream> GetOrCreateStreamAsync(ITorrentFileInfo file, FileAccess access) { if (!Streams.TryGetValue(file, out StreamData data)) { data = Streams[file] = new StreamData(); } var releaser = await data.Locker.EnterAsync(); if (data.Stream != null) { // If we are requesting write access and the current stream does not have it if (((access & FileAccess.Write) == FileAccess.Write) && !data.Stream.CanWrite) { logger.InfoFormatted("Didn't have write permission for {0} - reopening", file.Path); data.Stream.Dispose(); data.Stream = null; Count--; } } if (data.Stream == null) { if (!File.Exists(file.FullPath)) { if (!string.IsNullOrEmpty(Path.GetDirectoryName(file.FullPath))) { Directory.CreateDirectory(Path.GetDirectoryName(file.FullPath)); } NtfsSparseFile.CreateSparse(file.FullPath, file.Length); } data.Stream = StreamCreator(file, access); Count++; // Ensure that we truncate existing files which are too large if (data.Stream.Length > file.Length) { if (!data.Stream.CanWrite) { data.Stream.Dispose(); data.Stream = StreamCreator(file, FileAccess.ReadWrite); } await data.Stream.SetLengthAsync(file.Length); } } data.LastUsedStamp = Stopwatch.GetTimestamp(); MaybeRemoveOldestStream(); return(new RentedStream(data.Stream, releaser)); }