Ringbuffer在实时流缓冲的demo

实现ringbuffer,不需要用锁的方法,如下面:

用write read size 以及start end就可以定位问题


写入过程,总共6种情况:

1)write = read ,如果end-write >len 那么write = write + len 写入长度len

                                如果end-write <len 需要借用前面的位置,那么write = len-(end-write),写入长度len

2)write > read ,并且 end-write>len,那么write = write + len,写入长度为len

3)write < read,   并且 read-write>len,那么write = write+ len,写入长度为len

4)write走到队尾的情况,并且write > read,并且(end-write)+(read-start)>len,那么write = len-(end-write)

其余情况,无法写入数据。


读入过程,总共五种情况,也是一样的,如下:

1)write = read 无法读数据

2)write > read 情况  如果write - read > len 那么read = read+ len

                                       如果write - read < len ,那么无法读数据

3)write<read情况,说明写的快,如果end-read > len ,read = read+ len

                                                             如果end-read< len && (end-read) + (write-start)>len,那么read= len-(end-read)  

通过上述的分析可以发现,基本的场景就可以分析了,下面是java的demo,读取二机制,

这种很适合在实时流的缓冲设计,

但是有一个小问题,最后总是小于读取的len是无法读取的,

对于c++也可以参考实现,就是首地址,采取malloc,然后将地址传入就ok了!

请读者自行参考实现,不再写代码!


import java.io.File;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;


//环形数组缓冲区 缓冲区所能存放的数据为缓冲区大小的个数 减去1 为实际能存储的大小
public class RingBuffer {

private static byte[] buf=null;
private static int mStart;
private static int mEnd;
private static int mSize;
private static int mWrite;
private static int mRead;
//mSize = BUFFER_SIZE;
    //mAddrEnd = mAddrStart + BUFFER_SIZE;
   // mAddrWrite = mAddrStart;
   // mAddrRead = mAddrStart;


public RingBuffer(int s){//构造函数定义缓冲区的大小

buf = new byte[s];
mSize=buf.length;
mRead = mWrite = 0;
mStart=0;
mEnd=buf.length-1;
System.out.println("buf.length="+buf.length);
}

public boolean put(byte[] ar,int len){

int read = mRead;
int write = mWrite;
int end = mEnd;
int start = mStart;

if((read == write) ||
                ((read > write) && ((read - write) > len)) ||
                ((read < write) && ((end - write > len))))
        {
System.arraycopy(ar, 0, buf, write,len);
mWrite=mWrite + len;
System.out.println("<<<<<<<<<<<<<<<<<<write<<<<<<<<<<<<<<<<<<<<<<<<");
System.out.println("len = "+len);
System.out.println("read="+mRead);
System.out.println("write="+mWrite);
System.out.println(">>>>>>>>>>>>>>>>>>>write>>>>>>>>>>>>>>>>>>>>>>>");
return true;


        }
        else if((read < write) && (((end - write) + (read - start)) > len))
        {
       
            //memcpy((void*)write, (void*)buffer, (end - write));
            //memcpy((void*)start, (void*)(buffer + (end - write)),len - (end - write));
       
System.arraycopy(ar,0, buf,write,end-write);
System.arraycopy(ar, start, buf, end-write, len-(end-write));
System.out.println("write="+mWrite);
            mWrite= mWrite+len-mSize;
            System.out.println("===============write====================");
            System.out.println("len = "+len);
            System.out.println("read="+mRead);
System.out.println("write="+mWrite);
            System.out.println("===============write====================");
            return true;
        }
        else
        {
            System.out.println("写的空间不够!!!!!");
            System.out.println("len = "+len);
            System.out.println("read="+mRead);
System.out.println("write="+mWrite);
System.out.println("start="+mStart);
System.out.println("end="+mEnd);
System.out.println("写的空间不够!!!!!");
            return false;
        }

}

public byte[] get(int push_unit){

        
int read = mRead;
int write = mWrite;
int end = mEnd;
int start = mStart;
        /*if(read - mRead <= push_unit)
        {
        byte[] arr = new byte[write - read];
        System.out.println("push_unit = "+(write - read));
        System.arraycopy(buf,read, arr,0,write - read);
        mRead = mWrite;
        System.out.println("====55555555555555555555555=======");
System.out.println("read="+mRead);
System.out.println("write="+mWrite);
        System.out.println("====5555555555555555555555===========");
        return arr;
        }*/
        byte[] arr = new byte[push_unit];
if((write > (read + push_unit)) ||
                ((write < read) && ((end - read) > push_unit)))
        {
            //memcpy((void*)out_buffer, (void*)read, push_unit);
            //this.mRead = (unsigned char*)(read + push_unit);
System.arraycopy(buf,read, arr,0,push_unit);
mRead = mRead + push_unit;
System.out.println("-----------------read----------------------");
System.out.println("get_unit = "+push_unit);
System.out.println("read="+mRead);
System.out.println("write="+mWrite);
System.out.println("-----------------read-----------------------");
return arr;
        }
        else if((write < read) && (((write - start) + (end - read)) > push_unit))
        {
            //memcpy((void*)out_buffer, (void*)read, (int)(end - read));
            //memcpy((void*)((unsigned int) out_buffer + end - read), (void*)start, (int)(push_unit - (end-read)));
            //this.mRead = (unsigned char*)((read + push_unit) - mSize);
       
        System.arraycopy(buf,read, arr,0,end-read);
        System.arraycopy(buf,start, arr,end-read,push_unit-(end-read));
        mRead = mRead + push_unit - mSize;
        System.out.println("@@@@@@@@@@@@@@@@@@read@@@@@@@@@@@@@@@@@@@@@@@@@@@");
        System.out.println("get_unit = "+push_unit);
System.out.println("read="+mRead);
System.out.println("write="+mWrite);
System.out.println("@@@@@@@@@@@@@@@@@@read@@@@@@@@@@@@@@@@@@@@@@@@@@@");
        return arr;
        }
        else
        {
        System.out.println("读的空间不够!");
        System.out.println("get_unit = "+push_unit);
        System.out.println("read="+mRead);
System.out.println("write="+mWrite);
System.out.println("读的空间不够!");
            return null;
        }
      }

   public void reset_buffer() {

mStart=0;
mEnd=mStart+mSize;
mSize=buf.length;
mRead = mWrite = mStart;
System.out.println("buf.length=%d"+buf.length);
}
 
   
public static void main(String[] args){//测试

final RingBuffer ringbuf = new RingBuffer(1024*1024*100);
InputStream in = null;

new Thread() {

        public void run() {
              System.out.println("线程执行了。。。。。。。");
              //RingBuffer test = new RingBuffer(1048576);
              int push_unit = 1024*1024;
              byte[] getbytes = new byte[1024*1024];
              try {
sleep(100);
 } catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
 }
              File out_file = new File("F:/newfile.ts");
           FileOutputStream fop = null;
         try {
           if (!out_file.exists()) {
          out_file.createNewFile();
           }
           fop = new FileOutputStream(out_file);
           for(int i =0;i<10000000;i++){
             do{
              getbytes  = ringbuf.get(push_unit);
              if(getbytes == null)
              {
              sleep(10);
              }
              // if file doesnt exists, then create it
              if(getbytes != null)
                fop.write(getbytes);
              /*if(getbytes.length != push_unit){
              fop.flush();
              fop.close();
              return;
              }*/
             }while(getbytes != null);
           }
          }catch (Exception e1) {
             e1.printStackTrace();
         } finally {
             if (fop != null) {
                 try {
                fop.close();
                 } catch (IOException e1) {
                 }
             }
         }
        }
      }.start();
      
      


try {
        System.out.println("以字节为单位读取文件内容,一次读多个字节:");
        // 一次读多个字节
        String fileName = "F:/[MV] KARA - Jet Coaster Love (Dance Ver.) [1080p HD].webm";
        
        byte[] tempbytes = new byte[1024*1024];
        int byteread = 0;
        in = new FileInputStream(fileName);
      //getbytes  = buf.get(push_unit);
        File out = new File("F:/out.ts");
    FileOutputStream op = null;
    if (!out.exists()) {
    out.createNewFile();
    }
    op = new FileOutputStream(out);
        //showAvailableBytes(in);
        // 读入多个字节到字节数组中,byteread为一次读入的字节数
        while ((byteread = in.read(tempbytes)) != -1) { 
            
        //op.write(tempbytes);
        if(ringbuf.put(tempbytes,byteread)==false){
        //System.out.println("空间不够");
        return ;
        }
        }
        
    } catch (Exception e1) {
        e1.printStackTrace();
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e1) {
            }
        }
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值