|
@@ -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];
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|