From 177b7ce210e5bf1ffa0b2c2c4dbcaffa34540126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=A5=E6=B1=9D=E6=A3=8B=E8=8C=97?= <505554090@qq.com> Date: Mon, 15 May 2023 13:33:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DFilePool=E5=BC=82=E5=B8=B8bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/TouchSocket/Core/IO/FileIO/FilePool.cs | 32 +++++---- src/TouchSocket/Core/IO/FileIO/FileStorage.cs | 71 +++++++++---------- .../Core/IO/FileIO/FileStorageReader.cs | 33 +++++---- .../Core/IO/FileIO/FileStorageStream.cs | 39 +++++----- .../Core/IO/FileIO/FileStorageWriter.cs | 32 ++++----- src/TouchSocket/TouchSocket.csproj | 2 +- 6 files changed, 105 insertions(+), 104 deletions(-) diff --git a/src/TouchSocket/Core/IO/FileIO/FilePool.cs b/src/TouchSocket/Core/IO/FileIO/FilePool.cs index a477aee1..32e405de 100644 --- a/src/TouchSocket/Core/IO/FileIO/FilePool.cs +++ b/src/TouchSocket/Core/IO/FileIO/FilePool.cs @@ -81,13 +81,17 @@ namespace TouchSocket.Core } lock (m_locker) { - if (m_pathStorage.TryGetValue(fileInfo.FullName, out storage)) + storage = new FileStorage(fileInfo, FileAccess.Read); + if (m_pathStorage.TryAdd(fileInfo.FullName, storage)) { + Interlocked.Increment(ref storage.m_reference); return storage; } - FileStorage fileStorage = new FileStorage(fileInfo, FileAccess.Read); - m_pathStorage.TryAdd(fileInfo.FullName, fileStorage); - return fileStorage; + else + { + return GetFileStorageForRead(fileInfo); + } + } } @@ -127,13 +131,16 @@ namespace TouchSocket.Core } lock (m_locker) { - if (m_pathStorage.TryGetValue(fileInfo.FullName, out storage)) + storage = new FileStorage(fileInfo, FileAccess.Write); + if (m_pathStorage.TryAdd(fileInfo.FullName, storage)) { + Interlocked.Increment(ref storage.m_reference); return storage; } - FileStorage fileStorage = new FileStorage(fileInfo, FileAccess.Write); - m_pathStorage.TryAdd(fileInfo.FullName, fileStorage); - return fileStorage; + else + { + return GetFileStorageForWrite(fileInfo); + } } } @@ -279,8 +286,7 @@ namespace TouchSocket.Core path = Path.GetFullPath(path); if (m_pathStorage.TryGetValue(path, out FileStorage fileStorage)) { - Interlocked.Decrement(ref fileStorage.m_reference); - if (fileStorage.m_reference <= 0) + if (Interlocked.Decrement(ref fileStorage.m_reference) <= 0) { if (delayTime > 0) { @@ -318,15 +324,15 @@ namespace TouchSocket.Core private static void OnTimer(object state) { - List keys = new List(); - foreach (var item in m_pathStorage) + var keys = new List(); + foreach (KeyValuePair item in m_pathStorage) { if (DateTime.Now - item.Value.AccessTime > item.Value.AccessTimeout) { keys.Add(item.Key); } } - foreach (var item in keys) + foreach (string item in keys) { TryReleaseFile(item); } diff --git a/src/TouchSocket/Core/IO/FileIO/FileStorage.cs b/src/TouchSocket/Core/IO/FileIO/FileStorage.cs index 86a9ed10..35a800ba 100644 --- a/src/TouchSocket/Core/IO/FileIO/FileStorage.cs +++ b/src/TouchSocket/Core/IO/FileIO/FileStorage.cs @@ -33,18 +33,18 @@ namespace TouchSocket.Core /// internal FileStorage(FileInfo fileInfo, FileAccess fileAccess) : this() { - FileAccess = fileAccess; - FileInfo = fileInfo; - Path = fileInfo.FullName; - m_reference = 0; - FileStream = fileAccess == FileAccess.Read ? fileInfo.OpenRead() : fileInfo.OpenWrite(); - m_lockSlim = new ReaderWriterLockSlim(); + this.FileAccess = fileAccess; + this.FileInfo = fileInfo; + this.Path = fileInfo.FullName; + this.m_reference = 0; + this.FileStream = fileAccess == FileAccess.Read ? fileInfo.OpenRead() : fileInfo.OpenWrite(); + this.m_lockSlim = new ReaderWriterLockSlim(); } private FileStorage() { - AccessTime = DateTime.Now; - AccessTimeout = TimeSpan.FromSeconds(60); + this.AccessTime = DateTime.Now; + this.AccessTimeout = TimeSpan.FromSeconds(60); } /// @@ -81,7 +81,7 @@ namespace TouchSocket.Core /// /// 文件长度 /// - public long Length => FileStream.Length; + public long Length => this.FileStream.Length; /// /// 文件路径 @@ -91,7 +91,7 @@ namespace TouchSocket.Core /// /// 引用次数。 /// - public int Reference => m_reference; + public int Reference => this.m_reference; /// /// 创建一个只读的、已经缓存的文件信息。该操作不会占用文件句柄。 @@ -136,8 +136,8 @@ namespace TouchSocket.Core /// public void Flush() { - AccessTime = DateTime.Now; - FileStream.Flush(); + this.AccessTime = DateTime.Now; + this.FileStream.Flush(); } /// @@ -150,27 +150,27 @@ namespace TouchSocket.Core /// public int Read(long stratPos, byte[] buffer, int offset, int length) { - AccessTime = DateTime.Now; - using (WriteLock writeLock = new WriteLock(m_lockSlim)) + this.AccessTime = DateTime.Now; + using (var writeLock = new WriteLock(this.m_lockSlim)) { - if (m_disposedValue) + if (this.m_disposedValue) { - throw new ObjectDisposedException(GetType().FullName); + throw new ObjectDisposedException(this.GetType().FullName); } - if (FileAccess == FileAccess.Write) + if (this.FileAccess == FileAccess.Write) { throw new Exception("该流不允许读取。"); } - if (Cache) + if (this.Cache) { - int r = (int)Math.Min(m_fileData.Length - stratPos, length); - Array.Copy(m_fileData, stratPos, buffer, offset, r); + int r = (int)Math.Min(this.m_fileData.Length - stratPos, length); + Array.Copy(this.m_fileData, stratPos, buffer, offset, r); return r; } else { - FileStream.Position = stratPos; - return FileStream.Read(buffer, offset, length); + this.FileStream.Position = stratPos; + return this.FileStream.Read(buffer, offset, length); } } } @@ -184,7 +184,7 @@ namespace TouchSocket.Core /// public Result TryReleaseFile(int delayTime = 0) { - return FilePool.TryReleaseFile(Path, delayTime); + return FilePool.TryReleaseFile(this.Path, delayTime); } /// @@ -196,34 +196,33 @@ namespace TouchSocket.Core /// public void Write(long stratPos, byte[] buffer, int offset, int length) { - AccessTime = DateTime.Now; - using (WriteLock writeLock = new WriteLock(m_lockSlim)) + this.AccessTime = DateTime.Now; + using (var writeLock = new WriteLock(this.m_lockSlim)) { - if (m_disposedValue) + if (this.m_disposedValue) { - throw new ObjectDisposedException(GetType().FullName); + throw new ObjectDisposedException(this.GetType().FullName); } - if (FileAccess == FileAccess.Read) + if (this.FileAccess == FileAccess.Read) { throw new Exception("该流不允许写入。"); } - FileStream.Position = stratPos; - FileStream.Write(buffer, offset, length); - FileStream.Flush(); + this.FileStream.Position = stratPos; + this.FileStream.Write(buffer, offset, length); } } internal void Dispose() { - if (m_disposedValue) + if (this.m_disposedValue) { return; } - using (WriteLock writeLock = new WriteLock(m_lockSlim)) + using (var writeLock = new WriteLock(this.m_lockSlim)) { - m_disposedValue = true; - FileStream.SafeDispose(); - m_fileData = null; + this.m_disposedValue = true; + this.FileStream.SafeDispose(); + this.m_fileData = null; } } } diff --git a/src/TouchSocket/Core/IO/FileIO/FileStorageReader.cs b/src/TouchSocket/Core/IO/FileIO/FileStorageReader.cs index 01dcfdf2..59d4b4df 100644 --- a/src/TouchSocket/Core/IO/FileIO/FileStorageReader.cs +++ b/src/TouchSocket/Core/IO/FileIO/FileStorageReader.cs @@ -11,6 +11,8 @@ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ +using System; + namespace TouchSocket.Core { /// @@ -19,9 +21,6 @@ namespace TouchSocket.Core [IntelligentCoder.AsyncMethodPoster(Flags = IntelligentCoder.MemberFlags.Public)] public partial class FileStorageReader : DisposableObject { - private FileStorage m_fileStorage; - - private long m_position; /// /// 构造函数 @@ -29,7 +28,7 @@ namespace TouchSocket.Core /// public FileStorageReader(FileStorage fileStorage) { - m_fileStorage = fileStorage ?? throw new System.ArgumentNullException(nameof(fileStorage)); + this.FileStorage = fileStorage ?? throw new System.ArgumentNullException(nameof(fileStorage)); } /// @@ -38,31 +37,27 @@ namespace TouchSocket.Core ~FileStorageReader() { // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 - Dispose(disposing: false); + this.Dispose(disposing: false); } /// /// 文件存储器 /// - public FileStorage FileStorage => m_fileStorage; + public FileStorage FileStorage { get; private set; } /// /// 游标位置 /// public int Pos { - get => (int)m_position; - set => m_position = value; + get => (int)this.Position; + set => this.Position = value; } /// /// 游标位置 /// - public long Position - { - get => m_position; - set => m_position = value; - } + public long Position { get; set; } /// /// 读取数据到缓存区 @@ -73,8 +68,8 @@ namespace TouchSocket.Core /// public int Read(byte[] buffer, int offset, int length) { - int r = m_fileStorage.Read(m_position, buffer, offset, length); - m_position += r; + int r = this.FileStorage.Read(this.Position, buffer, offset, length); + this.Position += r; return r; } @@ -84,8 +79,12 @@ namespace TouchSocket.Core /// protected override void Dispose(bool disposing) { - FilePool.TryReleaseFile(m_fileStorage.Path); - m_fileStorage = null; + if (this.DisposedValue) + { + return; + } + FilePool.TryReleaseFile(this.FileStorage.Path); + this.FileStorage = null; base.Dispose(disposing); } } diff --git a/src/TouchSocket/Core/IO/FileIO/FileStorageStream.cs b/src/TouchSocket/Core/IO/FileIO/FileStorageStream.cs index 631937a3..f631e0a2 100644 --- a/src/TouchSocket/Core/IO/FileIO/FileStorageStream.cs +++ b/src/TouchSocket/Core/IO/FileIO/FileStorageStream.cs @@ -20,7 +20,6 @@ namespace TouchSocket.Core [IntelligentCoder.AsyncMethodPoster(Flags = IntelligentCoder.MemberFlags.Public)] public partial class FileStorageStream : Stream { - private readonly FileStorage m_fileStorage; private long m_position; /// @@ -29,7 +28,7 @@ namespace TouchSocket.Core /// public FileStorageStream(FileStorage fileStorage) { - m_fileStorage = fileStorage ?? throw new System.ArgumentNullException(nameof(fileStorage)); + this.FileStorage = fileStorage ?? throw new System.ArgumentNullException(nameof(fileStorage)); } /// @@ -38,38 +37,38 @@ namespace TouchSocket.Core ~FileStorageStream() { // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 - Dispose(disposing: false); + this.Dispose(disposing: false); } /// /// /// - public override bool CanRead => m_fileStorage.FileStream.CanRead; + public override bool CanRead => this.FileStorage.FileStream.CanRead; /// /// /// - public override bool CanSeek => m_fileStorage.FileStream.CanSeek; + public override bool CanSeek => this.FileStorage.FileStream.CanSeek; /// /// /// - public override bool CanWrite => m_fileStorage.FileStream.CanWrite; + public override bool CanWrite => this.FileStorage.FileStream.CanWrite; /// /// 文件存储器 /// - public FileStorage FileStorage => m_fileStorage; + public FileStorage FileStorage { get; private set; } /// /// /// - public override long Length => m_fileStorage.FileStream.Length; + public override long Length => this.FileStorage.FileStream.Length; /// /// /// - public override long Position { get => m_position; set => m_position = value; } + public override long Position { get => this.m_position; set => this.m_position = value; } /// /// @@ -77,7 +76,7 @@ namespace TouchSocket.Core [IntelligentCoder.AsyncMethodIgnore] public override void Flush() { - m_fileStorage.Flush(); + this.FileStorage.Flush(); } /// @@ -89,8 +88,8 @@ namespace TouchSocket.Core /// public override int Read(byte[] buffer, int offset, int count) { - int r = m_fileStorage.Read(m_position, buffer, offset, count); - m_position += r; + int r = this.FileStorage.Read(this.m_position, buffer, offset, count); + this.m_position += r; return r; } @@ -105,18 +104,18 @@ namespace TouchSocket.Core switch (origin) { case SeekOrigin.Begin: - m_position = offset; + this.m_position = offset; break; case SeekOrigin.Current: - m_position += offset; + this.m_position += offset; break; case SeekOrigin.End: - m_position = Length + offset; + this.m_position = this.Length + offset; break; } - return m_position; + return this.m_position; } /// @@ -125,7 +124,7 @@ namespace TouchSocket.Core /// public override void SetLength(long value) { - m_fileStorage.FileStream.SetLength(value); + this.FileStorage.FileStream.SetLength(value); } /// @@ -136,8 +135,8 @@ namespace TouchSocket.Core /// public override void Write(byte[] buffer, int offset, int count) { - m_fileStorage.Write(m_position, buffer, offset, count); - m_position += count; + this.FileStorage.Write(this.m_position, buffer, offset, count); + this.m_position += count; } /// @@ -146,7 +145,7 @@ namespace TouchSocket.Core /// protected override void Dispose(bool disposing) { - FilePool.TryReleaseFile(m_fileStorage.Path); + FilePool.TryReleaseFile(this.FileStorage.Path); base.Dispose(disposing); } } diff --git a/src/TouchSocket/Core/IO/FileIO/FileStorageWriter.cs b/src/TouchSocket/Core/IO/FileIO/FileStorageWriter.cs index 642ea228..6205f1b2 100644 --- a/src/TouchSocket/Core/IO/FileIO/FileStorageWriter.cs +++ b/src/TouchSocket/Core/IO/FileIO/FileStorageWriter.cs @@ -19,8 +19,6 @@ namespace TouchSocket.Core [IntelligentCoder.AsyncMethodPoster(Flags = IntelligentCoder.MemberFlags.Public)] public partial class FileStorageWriter : DisposableObject, IWrite { - private readonly FileStorage m_fileStorage; - private long m_position; /// /// 构造函数 @@ -28,7 +26,7 @@ namespace TouchSocket.Core /// public FileStorageWriter(FileStorage fileStorage) { - m_fileStorage = fileStorage ?? throw new System.ArgumentNullException(nameof(fileStorage)); + this.FileStorage = fileStorage ?? throw new System.ArgumentNullException(nameof(fileStorage)); } /// @@ -37,7 +35,7 @@ namespace TouchSocket.Core /// public virtual void Write(byte[] buffer) { - Write(buffer, 0, buffer.Length); + this.Write(buffer, 0, buffer.Length); } /// @@ -46,31 +44,27 @@ namespace TouchSocket.Core ~FileStorageWriter() { // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 - Dispose(disposing: false); + this.Dispose(disposing: false); } /// /// 文件存储器 /// - public FileStorage FileStorage => m_fileStorage; + public FileStorage FileStorage { get; private set; } /// /// 游标位置 /// public int Pos { - get => (int)m_position; - set => m_position = value; + get => (int)this.Position; + set => this.Position = value; } /// /// 游标位置 /// - public long Position - { - get => m_position; - set => m_position = value; - } + public long Position { get; set; } /// /// 移动Pos到流末尾 @@ -78,7 +72,7 @@ namespace TouchSocket.Core /// public long SeekToEnd() { - return Position = FileStorage.Length; + return this.Position = this.FileStorage.Length; } /// @@ -90,8 +84,8 @@ namespace TouchSocket.Core /// public void Write(byte[] buffer, int offset, int length) { - m_fileStorage.Write(m_position, buffer, offset, length); - m_position += length; + this.FileStorage.Write(this.Position, buffer, offset, length); + this.Position += length; } /// @@ -100,7 +94,11 @@ namespace TouchSocket.Core /// protected override void Dispose(bool disposing) { - FilePool.TryReleaseFile(m_fileStorage.Path); + if (this.DisposedValue) + { + return; + } + FilePool.TryReleaseFile(this.FileStorage.Path); base.Dispose(disposing); } } diff --git a/src/TouchSocket/TouchSocket.csproj b/src/TouchSocket/TouchSocket.csproj index 6fb19af3..47338db8 100644 --- a/src/TouchSocket/TouchSocket.csproj +++ b/src/TouchSocket/TouchSocket.csproj @@ -4,7 +4,7 @@ logo.ico True D:\MyStore\13_Doc\Keys\TouchSocket.snk - 1.3.1 + 1.3.2 8.0 若汝棋茗 Copyright © 2023 若汝棋茗 -- GitLab