曾需要实现这样一个功能:创建一个流然后一个线程往流中写入数据,而另一个线程从流中读取数据。刚开始想用 System.IO.MemoryStream 类,但发现它无法实现我要的功能。没办法,偷懒不成就只有自己动手写了。
1. RingMemoryStream 的特点
-
- 派生于 System.IO.Stream
- 先进先出
- 环形缓冲区
- 线程安全
- 自动扩展容量
2. 实现思路
[待写]
3. 代码
/*
* Author: Jason Sun (相交的平行线)
*
* Email: sjshjz@hotmail.com
*
* Copyright (C) Jason Sun. All Rights Reserved.
*/
using System;
using System.IO;
namespace AudioLib
{
/// <summary>
/// 派生于 System.IO.Stream 类,实现一个先进先出的环形内存流。支持分别在不同的线程中对流进行读写。
/// </summary>
public class RingMemoryStream : Stream
{
private const int INITCAPACITY = 4 * 1024; // 默认初始容量
private const int INCREMENTSIZE = 4 * 1024;// 自动扩展时一次最少扩展多少字节
private object m_synObject = new object(); // 同步对象
private byte[] m_buffer; // 内部缓冲区
private int m_capacity; // 缓冲区的容量
private int m_length; // 缓冲区中当前有效数据的长度
private bool m_expandable; // 是否可自动扩展容量
private int m_maxCapacity; // 可扩展到的最大容量
private int m_rPos; // 读指针的偏移位置(指向流中第一个有效字节)
private int m_wPos; // 写指针的偏移位置(指向流中最后一个有效字节之后的那个字节)
/// <summary>
/// 使用默认的初始容量以及可自动扩展初始化 RingMemoryStream 类的新实例。
/// </summary>
public RingMemoryStream()
: this(INITCAPACITY)
{
}
/// <summary>
/// 使用指定的初始容量以及可自动扩展初始化 RingMemoryStream 类的新实例。
/// </summary>
public RingMemoryStream(int capacity)
: this(capacity, true)
{
}
/// <summary>
/// 使用指定的容量和是否可自动扩展初始化 RingMemoryStream 类的新实例。
/// </summary>
/// <param name="capacity">指定流的初始容量。</param>
/// <param name="expandable">是否可自动扩展。</param>
public RingMemoryStream(int capacity, bool expandable)
: this(capacity,expandable,-1)
{
}
/// <summary>