磁盘上的循环缓冲区实现

时间:2013-02-26 13:42:36

标签: java disk cyclic circular-buffer

我需要一些帮助/提示,​​将基于内存的循环缓冲区转换为基于磁盘的...对Java中的文件进行读/写操作,以存储一系列图像。

在线研究我发现我需要:

* 不需要固定大小的帧,但为每个帧添加一个包含实际大小的标头,以及时间戳和标志。然后,您可以简单地记住第一个有效帧的标头的偏移量和最后一个有效帧结束的偏移量,并且您将能够实现FIFO循环缓冲区。 * 使用8的打包作为头结构,并将缓冲区填充为8的倍数,这样您就可以读取/写入文件而不会出现对齐错误。

以下是我现在使用的代码:

class CircularBuffer {  

private ImageIcon buffer[];
private int lastIdx;
private int firstIdx;
private int size;
private boolean empty;

/** default size */
static final int DEFAULT_SIZE = 50;

public CircularBuffer(int size) {
    this.size = size;
    this.clear();
}

public CircularBuffer() {
    this(CircularBuffer.DEFAULT_SIZE);
}

public synchronized void push(ImageIcon data) {
    buffer[this.lastIdx] = data;
    if( this.lastIdx == this.firstIdx && !this.empty) {
        this.firstIdx++;
        this.firstIdx %= this.size;
            }
    if (this.empty){
        this.empty = false;
            }
    this.lastIdx++;
    this.lastIdx %= this.size; 
}

public synchronized int getLength() {
    if (this.empty)
        return 0;
    int len = this.lastIdx - this.firstIdx;
    if (len < 0)
        len = this.size + len;
    return len == 0 ? this.size-1 : len;
}

public synchronized ImageIcon pop() {
    if (isEmpty()) {
        throw new IndexOutOfBoundsException("Empty buffer");
    }
    ImageIcon res = buffer[this.firstIdx];
    buffer[this.firstIdx] = null;
    this.firstIdx++;
    this.firstIdx %= this.size;
    if (this.firstIdx == this.lastIdx)
        this.empty = true;
    return res;
}

public synchronized boolean isEmpty() {
    return this.empty;
}

public void clear () {
    this.firstIdx = 0;
    this.lastIdx = 0;
    this.empty = true;
    this.buffer = new ImageIcon[size];
}

public int getSize() {
    return this.size;
}

}

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

从你的另一个问题来看,我建议你不需要为像基于磁盘的循环缓冲区这样先进的东西而烦恼。以下伪代码怎么样:

Start:
   lastFrame = 0
   Loop Until STOP_REQUESTED:
      get_new_image_frame
      lastFrame++
      if (lastFrame > maxFrames)
         lastFrame = 1
      EndIf
      write_image_to_disk_named("image" + lastFrame + ".jpg")
   EndLoop

   initialise_video_ready_to_add_frames()
   Loop:
      add_image_to_video("image" + lastFrame + ".jpg")
      lastFrame++
      if (lastFrame > maxFrames)
         lastFrame = 1
      EndIf
   EndLoop

答案 1 :(得分:0)

使用记忆MappedByteBuffer .. 那给你java - &gt;记忆 - &gt;磁盘和类似数组的API