注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

anqiang专栏

不要问细节是怎么搞的,源码说明一切

 
 
 

日志

 
 

BufferedIndexOutput源码分析  

2009-11-30 10:22:55|  分类: Lucene |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 

BufferedIndexOutput是一个对硬盘介质进行操作的抽象类。

源码展示:

package org.apache.lucene.store;

/**

 * Licensed to the Apache Software Foundation (ASF) under one or more

 * contributor license agreements.  See the NOTICE file distributed with

 * this work for additional information regarding copyright ownership.

 * The ASF licenses this file to You under the Apache License, Version 2.0

 * (the "License"); you may not use this file except in compliance with

 * the License.  You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

import java.io.IOException;

/** Base implementation class for buffered {@link IndexOutput}. */

public abstract class BufferedIndexOutput extends IndexOutput {

/**

 * 大小为16KB

 * 2^14

 */

  static final int BUFFER_SIZE = 16384;

  /**

   * 这个才是一个真正的buffer

   */

  private final byte[] buffer = new byte[BUFFER_SIZE];

  /**

   * 这个是文件的当前指针位置

   */

  private long bufferStart = 0;           // position in file of buffer

  private int bufferPosition = 0;         // position in buffer

  /** Writes a single byte.

   * @see IndexInput#readByte()

   */

  public void writeByte(byte b) throws IOException {

    if (bufferPosition >= BUFFER_SIZE)

      flush();

    buffer[bufferPosition++] = b;

  }

  /** Writes an array of bytes.

   * @param b the bytes to write

   * @param length the number of bytes to write

   * @see IndexInput#readBytes(byte[],int,int)

   * 写入的原理如下:

   * 如果当前buffer的剩余内存大于所需内存,则将需要写入的bytes暂时copy到buffer中

   * 在这种情况下,如果到达buffer块的末尾,则需要将buffer中的内容写入到文件中去。

   * 重新向该块buffer写入内容

   * 

   * 如果当前的buffer长度比需要写入的bytes的长度还要小,则不借助于buffer,直接将内容写入文件(或者其他介质)中;

   * 如果当前的buffer长度比需要写入的bytes的长度要大,则可以flush一次buffer后,还可以借助buffer.

   */

  public void writeBytes(byte[] b, int offset, int length) throws IOException {

    int bytesLeft = BUFFER_SIZE - bufferPosition;

    // is there enough space in the buffer?

    if (bytesLeft >= length) {

      // we add the data to the end of the buffer

      System.arraycopy(b, offset, bufferbufferPosition, length);

      bufferPosition += length;

      // if the buffer is full, flush it

      if (BUFFER_SIZE - bufferPosition == 0)

        flush();

    } else {

      // is data larger then buffer?

      if (length > BUFFER_SIZE) {

        // we flush the buffer

        if (bufferPosition > 0)

          flush();

        // and write data at once

        flushBuffer(b, offset, length);

        bufferStart += length;

      } else {

        // we fill/flush the buffer (until the input is written)

        int pos = 0; // position in the input data

        int pieceLength;

        while (pos < length) {

          pieceLength = (length - pos < bytesLeft) ? length - pos : bytesLeft;

          System.arraycopy(b, pos + offset, bufferbufferPosition, pieceLength);

          pos += pieceLength;

          bufferPosition += pieceLength;

          // if the buffer is full, flush it

          bytesLeft = BUFFER_SIZE - bufferPosition;

          if (bytesLeft == 0) {

            flush();

            bytesLeft = BUFFER_SIZE;

          }

        }

      }

    }

  }

  /** Forces any buffered output to be written. */

  /**

   * 1.将buffer中剩余的信息写入到文件中

   * 2.设置当前file的指针,重置buffer的位置

   */

  public void flush() throws IOException {

    flushBuffer(bufferbufferPosition);

    bufferStart += bufferPosition;

    bufferPosition = 0;

  }

  /** Expert: implements buffer write.  Writes bytes at the current position in

   * the output.

   * @param b the bytes to write

   * @param len the number of bytes to write

   */

  private void flushBuffer(byte[] b, int len) throws IOException {

    flushBuffer(b, 0, len);

  }

  /** Expert: implements buffer write.  Writes bytes at the current position in

   * the output.

   * 这个flushBuffer的工作由subClass 例如:SimpleFSDirectory 来实现

   * @param b the bytes to write

   * @param offset the offset in the byte array

   * @param len the number of bytes to write

   */

  protected abstract void flushBuffer(byte[] b, int offset, int len) throws IOException;

  

  /** Closes this stream to further operations. */

  public void close() throws IOException {

    flush();

  }

  /** Returns the current position in this file, where the next write will

   * occur.

   * @see #seek(long)

   */

  public long getFilePointer() {

    return bufferStart + bufferPosition;

  }

  /** Sets current position in this file, where the next write will occur.

   * @see #getFilePointer()

   */

  public void seek(long pos) throws IOException {

    flush();

    bufferStart = pos;

  }

  /** The number of bytes in the file. */

  public abstract long length() throws IOException;

}

public void writeBytes(byte[] b, int offset, int length) throws IOException

这个函数是写bytes数组中的信息到硬盘介质文件中,缓存大小为16KB。在这里借助了缓存的作用,在JDK中的BufferOutputStream的缓存大小为8KB。在这里为什么要设置为16KB?有待考虑。

public void flush() throws IOException

这个函数将缓存中的内容写入硬盘,重新将缓存的内容重置。

  评论这张
 
阅读(209)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017