Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        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));
        }