Browse Source

PooledMemoryStream

懒得勤快 2 years ago
parent
commit
3de49cdd08

+ 1 - 1
Masuit.Tools.Abstractions/Security/Encrypt.cs

@@ -37,7 +37,7 @@ namespace Masuit.Tools.Security
             using var cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
             cs.Write(inputByteArray, 0, inputByteArray.Length);
             cs.FlushFinalBlock();
-            foreach (byte b in ms.ToArray())
+            foreach (var b in ms)
             {
                 ret.AppendFormat($"{b:X2}");
             }

+ 13 - 14
Masuit.Tools.Abstractions/Systems/LargeMemoryStream.cs

@@ -33,9 +33,10 @@ public class LargeMemoryStream : Stream
     private int GetPageCount(long length)
     {
         int pageCount = (int)(length / PageSize) + 1;
-
-        if ((length % PageSize) == 0)
+        if (length % PageSize == 0)
+        {
             pageCount--;
+        }
 
         return pageCount;
     }
@@ -49,7 +50,7 @@ public class LargeMemoryStream : Stream
         else
         {
             var streamBuffers = new byte[_streamBuffers.Length + AllocStep][];
-            Array.Copy(_streamBuffers, streamBuffers, _streamBuffers.Length);
+            Buffer.BlockCopy(_streamBuffers, 0, streamBuffers, 0, _streamBuffers.Length);
             _streamBuffers = streamBuffers;
         }
 
@@ -58,15 +59,16 @@ public class LargeMemoryStream : Stream
 
     private void AllocSpaceIfNeeded(long value)
     {
-        if (value < 0)
-            throw new InvalidOperationException("AllocSpaceIfNeeded < 0");
-
-        if (value == 0)
-            return;
+        switch (value)
+        {
+            case < 0:
+                throw new InvalidOperationException("AllocSpaceIfNeeded < 0");
+            case 0:
+                return;
+        }
 
         int currentPageCount = GetPageCount(_allocatedBytes);
         int neededPageCount = GetPageCount(value);
-
         while (currentPageCount < neededPageCount)
         {
             if (currentPageCount == _pageCount)
@@ -138,7 +140,6 @@ public class LargeMemoryStream : Stream
         int currentOffset = (int)(_position % PageSize);
         int currentLength = PageSize - currentOffset;
         long startPosition = _position;
-
         if (startPosition + count > _length)
         {
             count = (int)(_length - startPosition);
@@ -151,7 +152,7 @@ public class LargeMemoryStream : Stream
                 currentLength = count;
             }
 
-            Array.Copy(_streamBuffers[currentPage++], currentOffset, buffer, offset, currentLength);
+            Buffer.BlockCopy(_streamBuffers[currentPage++], currentOffset, buffer, offset, currentLength);
             offset += currentLength;
             _position += currentLength;
             count -= currentLength;
@@ -200,7 +201,6 @@ public class LargeMemoryStream : Stream
 
         int currentPageCount = GetPageCount(_allocatedBytes);
         int neededPageCount = GetPageCount(value);
-
         while (currentPageCount > neededPageCount)
         {
             ArrayPool<byte>.Shared.Return(_streamBuffers[--currentPageCount], true);
@@ -228,7 +228,7 @@ public class LargeMemoryStream : Stream
                 currentLength = count;
             }
 
-            Array.Copy(buffer, offset, _streamBuffers[currentPage++], currentOffset, currentLength);
+            Buffer.BlockCopy(buffer, offset, _streamBuffers[currentPage++], currentOffset, currentLength);
             offset += currentLength;
             _position += currentLength;
             count -= currentLength;
@@ -245,7 +245,6 @@ public class LargeMemoryStream : Stream
             _isDisposed = true;
             Position = 0;
             _length = 0;
-
             if (_streamBuffers != null)
             {
                 foreach (var bytes in _streamBuffers)

+ 85 - 9
Masuit.Tools.Abstractions/Systems/PooledMemoryStream.cs

@@ -1,5 +1,7 @@
 using System;
 using System.Buffers;
+using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 using System.Runtime.CompilerServices;
 
@@ -8,7 +10,7 @@ namespace Masuit.Tools.Systems;
 /// <summary>
 /// 池化内存流
 /// </summary>
-public sealed class PooledMemoryStream : Stream
+public sealed class PooledMemoryStream : Stream, IEnumerable<byte>
 {
     /// <summary>
     /// 终结器
@@ -31,7 +33,7 @@ public sealed class PooledMemoryStream : Stream
 
     public PooledMemoryStream(byte[] buffer) : this(ArrayPool<byte>.Shared, buffer.Length)
     {
-        Array.Copy(buffer, 0, _data, 0, buffer.Length);
+        Buffer.BlockCopy(buffer, 0, _data, 0, buffer.Length);
     }
 
     public PooledMemoryStream(ArrayPool<byte> arrayPool, int capacity = 0)
@@ -76,10 +78,16 @@ public sealed class PooledMemoryStream : Stream
         AssertNotDisposed();
     }
 
+    /// <summary>
+    /// 读取到字节数组
+    /// </summary>
+    /// <param name="buffer"></param>
+    /// <param name="offset"></param>
+    /// <param name="count"></param>
+    /// <returns></returns>
     public override int Read(byte[] buffer, int offset, int count)
     {
         AssertNotDisposed();
-
         if (count == 0)
         {
             return 0;
@@ -91,11 +99,17 @@ public sealed class PooledMemoryStream : Stream
         return (int)available;
     }
 
+    /// <summary>
+    /// 改变游标位置
+    /// </summary>
+    /// <param name="offset"></param>
+    /// <param name="origin"></param>
+    /// <returns></returns>
+    /// <exception cref="ArgumentOutOfRangeException"></exception>
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
     public override long Seek(long offset, SeekOrigin origin)
     {
         AssertNotDisposed();
-
         switch (origin)
         {
             case SeekOrigin.Current:
@@ -138,10 +152,14 @@ public sealed class PooledMemoryStream : Stream
         }
     }
 
+    /// <summary>
+    /// 设置内容长度
+    /// </summary>
+    /// <param name="value"></param>
+    /// <exception cref="ArgumentOutOfRangeException"></exception>
     public override void SetLength(long value)
     {
         AssertNotDisposed();
-
         if (value < 0)
         {
             throw new ArgumentOutOfRangeException(nameof(value));
@@ -159,11 +177,16 @@ public sealed class PooledMemoryStream : Stream
         }
     }
 
+    /// <summary>
+    /// 写入到字节数组
+    /// </summary>
+    /// <param name="buffer"></param>
+    /// <param name="offset"></param>
+    /// <param name="count"></param>
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
     public override void Write(byte[] buffer, int offset, int count)
     {
         AssertNotDisposed();
-
         if (count == 0)
         {
             return;
@@ -174,11 +197,16 @@ public sealed class PooledMemoryStream : Stream
             SetCapacity((int)(OverExpansionFactor * (Position + count)));
         }
 
-        Buffer.BlockCopy(buffer, offset, _data, (int)Position, count);
+        Array.Copy(buffer, offset, _data, Position, count);
         Position += count;
         _length = (int)Math.Max(Position, _length);
     }
 
+    /// <summary>
+    /// 写入到另一个流
+    /// </summary>
+    /// <param name="stream"></param>
+    /// <exception cref="ArgumentNullException"></exception>
     public void WriteTo(Stream stream)
     {
         if (stream == null)
@@ -190,6 +218,36 @@ public sealed class PooledMemoryStream : Stream
         stream.Write(_data, 0, (int)Length);
     }
 
+    /// <summary>
+    /// 获取流的字节数组
+    /// </summary>
+    /// <returns></returns>
+    public byte[] GetBuffer()
+    {
+        AssertNotDisposed();
+        if (_data.Length == Length)
+        {
+            return _data;
+        }
+
+        var buffer = new byte[Length];
+        Buffer.BlockCopy(_data, 0, buffer, 0, buffer.Length);
+        return buffer;
+    }
+
+    /// <summary>
+    /// 获取流的字节数组
+    /// </summary>
+    /// <returns></returns>
+    public byte[] ToArray()
+    {
+        return GetBuffer();
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="disposing"></param>
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
     protected override void Dispose(bool disposing)
     {
@@ -212,10 +270,9 @@ public sealed class PooledMemoryStream : Stream
     private void SetCapacity(int newCapacity)
     {
         var newData = _pool.Rent(newCapacity);
-
         if (_data != null)
         {
-            Buffer.BlockCopy(_data, 0, newData, 0, (int)Position);
+            Array.Copy(_data, 0, newData, 0, Position);
             _pool.Return(_data);
         }
 
@@ -230,4 +287,23 @@ public sealed class PooledMemoryStream : Stream
             throw new ObjectDisposedException(nameof(PooledMemoryStream));
         }
     }
+
+    /// <summary>Returns an enumerator that iterates through a collection.</summary>
+    /// <returns>An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.</returns>
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+        return GetEnumerator();
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <returns></returns>
+    public IEnumerator<byte> GetEnumerator()
+    {
+        for (var i = 0; i < Length; i++)
+        {
+            yield return _data[i];
+        }
+    }
 }

+ 6 - 27
NetCoreTest/Program.cs

@@ -1,29 +1,8 @@
-using Masuit.Tools.AspNetCore.ModelBinder;
-using Masuit.Tools.Files;
-using Masuit.Tools.Media;
+using Masuit.Tools.Systems;
 
-var stream = File.Open(@"D:\images\QQ½ØÍ¼20190923195408.jpg", FileMode.Open, FileAccess.ReadWrite);
-var watermarker = new ImageWatermarker(stream);
-var ms = watermarker.AddWatermark(File.OpenRead(@"D:\images\QQ½ØÍ¼20190923195408_¿´Í¼Íõ.png"), 0.5f);
-ms.SaveFile(@"Y:\1.jpg");
-Console.WriteLine(1);
-Console.ReadKey();
-
-var builder = WebApplication.CreateBuilder(args);
-builder.Services.AddControllers(options => options.ModelBinderProviders.InsertBodyOrDefaultBinding());
-builder.Services.AddEndpointsApiExplorer();
-builder.Services.AddSwaggerGen();
-
-var app = builder.Build();
-
-if (app.Environment.IsDevelopment())
+var ms = new PooledMemoryStream();
+ms.Write(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, 0, 9);
+foreach (var b in ms)
 {
-    app.UseSwagger();
-    app.UseSwaggerUI();
-}
-
-app.UseAuthorization();
-
-app.MapControllers();
-
-app.Run();
+    Console.WriteLine(b);
+}